You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

134 lines
4.9 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. # -*- coding: utf-8 -*-
  2. ##############################################################################
  3. #
  4. # OpenERP, Open Source Management Solution
  5. # This module copyright (C) 2012 Therp BV (<http://therp.nl>).
  6. #
  7. # This program is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU Affero General Public License as
  9. # published by the Free Software Foundation, either version 3 of the
  10. # License, or (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU Affero General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU Affero General Public License
  18. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. #
  20. ##############################################################################
  21. import logging
  22. from openerp import models
  23. from openerp import fields
  24. from openerp import api
  25. from string import Template
  26. _logger = logging.getLogger(__name__)
  27. class LDAPOperator(models.AbstractModel):
  28. _name = "res.company.ldap.operator"
  29. def operators(self):
  30. return ('contains', 'equals', 'query')
  31. def contains(self, ldap_entry, attribute, value, ldap_config, company):
  32. return (attribute in ldap_entry[1]) and \
  33. (value in ldap_entry[1][attribute])
  34. def equals(self, ldap_entry, attribute, value, ldap_config, company):
  35. return attribute in ldap_entry[1] and \
  36. unicode(value) == unicode(ldap_entry[1][attribute])
  37. def query(self, ldap_entry, attribute, value, ldap_config, company):
  38. query_string = Template(value).safe_substitute(dict(
  39. [(attr, ldap_entry[1][attr][0]) for attr in ldap_entry[1]]
  40. )
  41. )
  42. _logger.debug('evaluating query group mapping, filter: %s' %
  43. query_string)
  44. results = company.query(ldap_config, query_string)
  45. _logger.debug(results)
  46. return bool(results)
  47. class CompanyLDAPGroupMapping(models.Model):
  48. _name = 'res.company.ldap.group_mapping'
  49. _rec_name = 'ldap_attribute'
  50. _order = 'ldap_attribute'
  51. def _get_operators(self):
  52. op_obj = self.env['res.company.ldap.operator']
  53. operators = [(op, op) for op in op_obj.operators()]
  54. return tuple(operators)
  55. ldap_id = fields.Many2one('res.company.ldap', 'LDAP server', required=True)
  56. ldap_attribute = fields.Char(
  57. 'LDAP attribute',
  58. help='The LDAP attribute to check.\n'
  59. 'For active directory, use memberOf.')
  60. operator = fields.Selection(
  61. _get_operators, 'Operator',
  62. help='The operator to check the attribute against the value\n'
  63. 'For active directory, use \'contains\'', required=True)
  64. value = fields.Char(
  65. 'Value',
  66. help='The value to check the attribute against.\n'
  67. 'For active directory, use the dn of the desired group',
  68. required=True)
  69. group = fields.Many2one(
  70. 'res.groups', 'OpenERP group',
  71. help='The OpenERP group to assign', required=True)
  72. class CompanyLDAP(models.Model):
  73. _inherit = 'res.company.ldap'
  74. group_mappings = fields.One2many(
  75. 'res.company.ldap.group_mapping',
  76. 'ldap_id', 'Group mappings',
  77. help='Define how OpenERP groups are assigned to ldap users')
  78. only_ldap_groups = fields.Boolean(
  79. 'Only ldap groups',
  80. help='If this is checked, manual changes to group membership are '
  81. 'undone on every login (so OpenERP groups are always synchronous '
  82. 'with LDAP groups). If not, manually added groups are preserved.')
  83. _default = {
  84. 'only_ldap_groups': False,
  85. }
  86. def map_groups(self, user_id, ldap_config, ldap_entry):
  87. user_obj = self.env['res.users']
  88. operator_obj = self.env['res.company.ldap.operator']
  89. user = user_obj.browse(user_id)
  90. if self.only_ldap_groups:
  91. _logger.debug('deleting all groups from user %d' % user_id)
  92. user.write({'groups_id': [(5, )]})
  93. for mapping in self.group_mappings:
  94. operator = getattr(operator_obj, mapping.operator)
  95. _logger.debug('checking mapping %s' % mapping)
  96. if operator(ldap_entry, mapping['ldap_attribute'],
  97. mapping['value'], ldap_config, self):
  98. _logger.debug('adding user %d to group %s' %
  99. (user_id, mapping.group.name))
  100. user.write({'groups_id': [(4, mapping.group.id)]})
  101. @api.model
  102. def get_or_create_user(self, ldap_config, login, ldap_entry):
  103. user_id = super(CompanyLDAP, self).get_or_create_user(
  104. ldap_config, login, ldap_entry)
  105. if user_id:
  106. self.browse(ldap_config['id']).map_groups(user_id, ldap_config,
  107. ldap_entry)
  108. return user_id