diff --git a/users_ldap_groups/__openerp__.py b/users_ldap_groups/__openerp__.py index 98acddbab..044301a31 100644 --- a/users_ldap_groups/__openerp__.py +++ b/users_ldap_groups/__openerp__.py @@ -20,11 +20,11 @@ ############################################################################## { -"name" : "Groups assignment", -"version" : "1.2", -"depends" : ["auth_ldap"], -"author" : "Therp BV", -"description": """ + "name": "Groups assignment", + "version": "1.2", + "depends": ["auth_ldap"], + "author": "Therp BV", + "description": """ Adds user accounts to groups based on rules defined by the administrator. Usage: @@ -35,7 +35,7 @@ ldap server]. Decide whether you want only groups mapped from ldap (Only ldap groups=y) or a mix of manually set groups and ldap groups (Only ldap groups=n). Setting this to 'no' will result in users never losing privileges when you remove them from a -ldap group, so that's a potential security issue. It is still the default to +ldap group, so that's a potential security issue. It is still the default to prevent losing group information by accident. For active directory, use LDAP attribute 'memberOf' and operator 'contains'. @@ -46,17 +46,16 @@ For posix accounts, use operator 'query' and a value like (&(cn=bzr)(objectClass=posixGroup)(memberUid=$uid)) The operator query matches if the filter in value returns something, and value -can contain $[attribute] which will be replaced by the first value of the +can contain $[attribute] which will be replaced by the first value of the user's ldap record's attribute named [attribute]. """, -"category" : "Tools", -"data" : [ - 'users_ldap_groups.xml', - 'security/ir.model.access.csv', -], -"installable": True, -"external_dependencies" : { - 'python' : ['ldap'], -}, + "category": "Tools", + "data": [ + 'users_ldap_groups.xml', + 'security/ir.model.access.csv', + ], + "installable": True, + "external_dependencies": { + 'python': ['ldap'], + }, } -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/users_ldap_groups/users_ldap_groups.py b/users_ldap_groups/users_ldap_groups.py index 71db80338..9aaa1e71b 100644 --- a/users_ldap_groups/users_ldap_groups.py +++ b/users_ldap_groups/users_ldap_groups.py @@ -23,76 +23,85 @@ from openerp.osv import fields, orm import logging import users_ldap_groups_operators import inspect -import sys + class CompanyLDAPGroupMapping(orm.Model): - _name='res.company.ldap.group_mapping' - _rec_name='ldap_attribute' - _order='ldap_attribute' + _name = 'res.company.ldap.group_mapping' + _rec_name = 'ldap_attribute' + _order = 'ldap_attribute' - def _get_operators(self, cr, uid, context=None): - operators=[] - for name, operator in inspect.getmembers(users_ldap_groups_operators, - lambda cls: inspect.isclass(cls) - and cls!=users_ldap_groups_operators.LDAPOperator): - operators.append((name, name)) - return tuple(operators) + def _get_operators(self, cr, uid, context=None): + operators = [] + members = inspect.getmembers( + users_ldap_groups_operators, + lambda cls: inspect.isclass(cls) + and cls != users_ldap_groups_operators.LDAPOperator) + for name, operator in members: + operators.append((name, name)) + return tuple(operators) - _columns={ - 'ldap_id': fields.many2one('res.company.ldap', 'LDAP server', - required=True), - 'ldap_attribute': fields.char('LDAP attribute', size=64, + _columns = { + 'ldap_id': fields.many2one('res.company.ldap', 'LDAP server', required=True), + 'ldap_attribute': fields.char( + 'LDAP attribute', size=64, help='The LDAP attribute to check.\n' - 'For active directory, use memberOf.'), - 'operator': fields.selection(_get_operators, 'Operator', + 'For active directory, use memberOf.'), + 'operator': fields.selection( + _get_operators, 'Operator', help='The operator to check the attribute against the value\n' 'For active directory, use \'contains\'', required=True), - 'value': fields.char('Value', size=1024, + 'value': fields.char( + 'Value', size=1024, help='The value to check the attribute against.\n' - 'For active directory, use the dn of the desired group', + 'For active directory, use the dn of the desired group', required=True), - 'group': fields.many2one('res.groups', 'OpenERP group', + 'group': fields.many2one( + 'res.groups', 'OpenERP group', help='The OpenERP group to assign', required=True), } + class CompanyLDAP(orm.Model): - _inherit='res.company.ldap' + _inherit = 'res.company.ldap' - _columns={ - 'group_mappings': fields.one2many('res.company.ldap.group_mapping', - 'ldap_id', 'Group mappings', - help='Define how OpenERP groups are assigned to ldap users'), - 'only_ldap_groups': fields.boolean('Only ldap groups', - help='If this is checked, manual changes to group membership are ' - 'undone on every login (so OpenERP groups are always synchronous ' - 'with LDAP groups). If not, manually added groups are preserved.') - } + _columns = { + 'group_mappings': fields.one2many( + 'res.company.ldap.group_mapping', + 'ldap_id', 'Group mappings', + help='Define how OpenERP groups are assigned to ldap users'), + 'only_ldap_groups': fields.boolean( + 'Only ldap groups', + help='If this is checked, manual changes to group membership are ' + 'undone on every login (so OpenERP groups are always synchronous ' + 'with LDAP groups). If not, manually added groups are preserved.') + } - _default={ - 'only_ldap_groups': False - } + _default = { + 'only_ldap_groups': False, + } - def get_or_create_user(self, cr, uid, conf, login, ldap_entry, context=None): - user_id=super(CompanyLDAP, self).get_or_create_user(cr, uid, conf, login, - ldap_entry, context) - if not user_id: - return user_id - logger=logging.getLogger('users_ldap_groups') - mappingobj=self.pool.get('res.company.ldap.group_mapping') - userobj=self.pool.get('res.users') - conf_all=self.read(cr, uid, conf['id'], ['only_ldap_groups']) - if(conf_all['only_ldap_groups']): - logger.debug('deleting all groups from user %d' % user_id) - userobj.write(cr, uid, [user_id], {'groups_id': [(5, )]}) + def get_or_create_user(self, cr, uid, conf, login, ldap_entry, context=None): + user_id = super(CompanyLDAP, self).get_or_create_user(cr, uid, conf, login, + ldap_entry, context) + if not user_id: + return user_id + logger = logging.getLogger('users_ldap_groups') + mappingobj = self.pool.get('res.company.ldap.group_mapping') + userobj = self.pool.get('res.users') + conf_all = self.read(cr, uid, conf['id'], ['only_ldap_groups']) + if(conf_all['only_ldap_groups']): + logger.debug('deleting all groups from user %d' % user_id) + userobj.write(cr, uid, [user_id], {'groups_id': [(5, )]}, context=context) - for mapping in mappingobj.read(cr, uid, mappingobj.search(cr, uid, - [('ldap_id', '=', conf['id'])]), []): - operator=getattr(users_ldap_groups_operators, mapping['operator'])() - logger.debug('checking mapping %s' % mapping) - if operator.check_value(ldap_entry, mapping['ldap_attribute'], - mapping['value'], conf, self, logger): - logger.debug('adding user %d to group %s' % - (user_id, mapping['group'][1])) - userobj.write(cr, uid, [user_id], - {'groups_id': [(4, mapping['group'][0])]}) - return user_id + for mapping in mappingobj.read(cr, uid, mappingobj.search( + cr, uid, [('ldap_id', '=', conf['id'])]), []): + operator = getattr(users_ldap_groups_operators, mapping['operator'])() + logger.debug('checking mapping %s' % mapping) + if operator.check_value(ldap_entry, mapping['ldap_attribute'], + mapping['value'], conf, self, logger): + logger.debug('adding user %d to group %s' % + (user_id, mapping['group'][1])) + userobj.write(cr, uid, [user_id], + {'groups_id': [(4, mapping['group'][0])]}, + context=context) + return user_id diff --git a/users_ldap_groups/users_ldap_groups_operators.py b/users_ldap_groups/users_ldap_groups_operators.py index 9706459e9..4de745fbf 100644 --- a/users_ldap_groups/users_ldap_groups_operators.py +++ b/users_ldap_groups/users_ldap_groups_operators.py @@ -20,25 +20,28 @@ ############################################################################## from string import Template + class LDAPOperator: - pass + pass + class contains(LDAPOperator): - def check_value(self, ldap_entry, attribute, value, ldap_config, company, - logger): - return (attribute in ldap_entry[1]) and (value in ldap_entry[1][attribute]) + def check_value(self, ldap_entry, attribute, value, ldap_config, company, logger): + return (attribute in ldap_entry[1]) and (value in ldap_entry[1][attribute]) + class equals(LDAPOperator): - def check_value(self, ldap_entry, attribute, value, ldap_config, company, - logger): - return (attribute in ldap_entry[1]) and (str(value)==str(ldap_entry[1][attribute])) + def check_value(self, ldap_entry, attribute, value, ldap_config, company, logger): + return attribute in ldap_entry[1] and unicode(value) == unicode(ldap_entry[1][attribute]) + class query(LDAPOperator): - def check_value(self, ldap_entry, attribute, value, ldap_config, company, - logger): - query_string=Template(value).safe_substitute(dict([(attribute, - ldap_entry[1][attribute][0]) for attribute in ldap_entry[1]])) - logger.debug('evaluating query group mapping, filter: %s'%query_string) - results=company.query(ldap_config, query_string) - logger.debug(results) - return bool(results) + def check_value(self, ldap_entry, attribute, value, ldap_config, company, logger): + query_string = Template(value).safe_substitute(dict( + [(attr, ldap_entry[1][attribute][0]) for attr in ldap_entry[1]] + ) + ) + logger.debug('evaluating query group mapping, filter: %s' % query_string) + results = company.query(ldap_config, query_string) + logger.debug(results) + return bool(results)