diff --git a/users_ldap_groups/README.rst b/users_ldap_groups/README.rst new file mode 100644 index 000000000..2dbc81de3 --- /dev/null +++ b/users_ldap_groups/README.rst @@ -0,0 +1,64 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :alt: License: AGPL-3 + +users_ldap_groups +================= + +Adds user accounts to groups based on rules defined by the administrator. + + +Usage +===== + +Define mappings in Settings->Companies->[your company]->tab configuration->[ +your 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 +prevent losing group information by accident. + +For active directory, use LDAP attribute 'memberOf' and operator 'contains'. +Fill in the DN of the windows group as value and choose an OpenERP group users +with this windows group are to be assigned to. + +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 +user's ldap record's attribute named [attribute]. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed feedback +`here `_. + + +Credits +======= + +Contributors +------------ + +* Therp BV +* Giacomo Spettoli + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit http://odoo-community.org. diff --git a/users_ldap_groups/__init__.py b/users_ldap_groups/__init__.py index 4db4e4cb2..d1066f41b 100644 --- a/users_ldap_groups/__init__.py +++ b/users_ldap_groups/__init__.py @@ -19,4 +19,4 @@ # ############################################################################## -import users_ldap_groups # noqa +from . import users_ldap_groups diff --git a/users_ldap_groups/__openerp__.py b/users_ldap_groups/__openerp__.py index 9b63fec86..6014447dc 100644 --- a/users_ldap_groups/__openerp__.py +++ b/users_ldap_groups/__openerp__.py @@ -27,28 +27,6 @@ "license": "AGPL-3", "description": """ Adds user accounts to groups based on rules defined by the administrator. - -Usage: - -Define mappings in Settings->Companies->[your company]->tab configuration->[ -your 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 -prevent losing group information by accident. - -For active directory, use LDAP attribute 'memberOf' and operator 'contains'. -Fill in the DN of the windows group as value and choose an OpenERP group users -with this windows group are to be assigned to. - -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 -user's ldap record's attribute named [attribute]. """, "category": "Tools", "data": [ diff --git a/users_ldap_groups/users_ldap_groups.py b/users_ldap_groups/users_ldap_groups.py index 68b925c67..b99ae0fea 100644 --- a/users_ldap_groups/users_ldap_groups.py +++ b/users_ldap_groups/users_ldap_groups.py @@ -23,8 +23,36 @@ from openerp import models from openerp import fields from openerp import api import logging -import users_ldap_groups_operators -import inspect +from string import Template + + +class LDAPOperator(models.TransientModel): + _name = "res.company.ldap.operator" + + def operators(self): + return ('contains', 'equals', 'query') + + def contains(self, ldap_entry, attribute, value, ldap_config, company, + logger): + return (attribute in ldap_entry[1]) and \ + (value in ldap_entry[1][attribute]) + + def equals(self, ldap_entry, attribute, value, ldap_config, company, + logger): + return attribute in ldap_entry[1] and \ + unicode(value) == unicode(ldap_entry[1][attribute]) + + def query(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) class CompanyLDAPGroupMapping(models.Model): @@ -33,19 +61,13 @@ class CompanyLDAPGroupMapping(models.Model): _order = 'ldap_attribute' def _get_operators(self): - 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)) + op_obj = self.env['res.company.ldap.operator'] + operators = [(op, op) for op in op_obj.operators()] return tuple(operators) ldap_id = fields.Many2one('res.company.ldap', 'LDAP server', required=True) ldap_attribute = fields.Char( - 'LDAP attribute', size=64, + 'LDAP attribute', help='The LDAP attribute to check.\n' 'For active directory, use memberOf.') operator = fields.Selection( @@ -53,7 +75,7 @@ class CompanyLDAPGroupMapping(models.Model): 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', help='The value to check the attribute against.\n' 'For active directory, use the dn of the desired group', required=True) @@ -81,6 +103,7 @@ class CompanyLDAP(models.Model): @api.model def get_or_create_user(self, conf, login, ldap_entry): + op_obj = self.env['res.company.ldap.operator'] id_ = conf['id'] this = self.browse(id_) user_id = super(CompanyLDAP, self).get_or_create_user( @@ -95,11 +118,10 @@ class CompanyLDAP(models.Model): user.write({'groups_id': [(5, )]}) for mapping in this.group_mappings: - operator = mapping.operator - operator = getattr(users_ldap_groups_operators, mapping.operator)() + operator = getattr(op_obj, mapping.operator) logger.debug('checking mapping %s' % mapping) - if operator.check_value(ldap_entry, mapping['ldap_attribute'], - mapping['value'], conf, self, logger): + if operator(ldap_entry, mapping['ldap_attribute'], + mapping['value'], conf, self, logger): logger.debug('adding user %d to group %s' % (user_id, mapping.group.name)) user.write({'groups_id': [(4, mapping.group.id)]}) diff --git a/users_ldap_groups/users_ldap_groups_operators.py b/users_ldap_groups/users_ldap_groups_operators.py deleted file mode 100644 index e4354a825..000000000 --- a/users_ldap_groups/users_ldap_groups_operators.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# This module copyright (C) 2012 Therp BV (). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## -from string import Template - - -class LDAPOperator: - 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]) - - -class equals(LDAPOperator): - 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( - [(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)