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.

186 lines
7.0 KiB

7 years ago
  1. ###################################################################################
  2. #
  3. # Copyright (C) 2017 MuK IT GmbH
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU Affero General Public License as
  7. # published by the Free Software Foundation, either version 3 of the
  8. # License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU Affero General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU Affero General Public License
  16. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. #
  18. ###################################################################################
  19. import logging
  20. from odoo import _, SUPERUSER_ID
  21. from odoo import models, api, fields
  22. from odoo.exceptions import AccessError
  23. _logger = logging.getLogger(__name__)
  24. class BaseModelAccessGroups(models.AbstractModel):
  25. _name = 'muk_security.access_groups'
  26. _description = "MuK Access Groups Model"
  27. _inherit = 'muk_security.access'
  28. # Set it to True to enforced security even if no group has been set
  29. _strict_security = False
  30. #----------------------------------------------------------
  31. # Function
  32. #----------------------------------------------------------
  33. @api.model
  34. def _add_magic_fields(self):
  35. super(BaseModelAccessGroups, self)._add_magic_fields()
  36. def add(name, field):
  37. if name not in self._fields:
  38. self._add_field(name, field)
  39. base, model = self._name.split(".")
  40. add('groups', fields.Many2many(
  41. _module=base,
  42. comodel_name='muk_security.groups',
  43. relation='muk_groups_%s_rel' % model,
  44. column1='aid',
  45. column2='gid',
  46. string="Groups",
  47. automatic=True))
  48. add('complete_groups', fields.Many2many(
  49. _module=base,
  50. comodel_name='muk_security.groups',
  51. relation='muk_groups_complete_%s_rel' % model,
  52. column1='aid',
  53. column2='gid',
  54. string="Complete Groups",
  55. compute='_compute_groups',
  56. store=True,
  57. automatic=True))
  58. @api.model
  59. def _get_no_access_ids(self):
  60. base, model = self._name.split(".")
  61. if not self._strict_security:
  62. sql = '''
  63. SELECT id
  64. FROM %s a
  65. WHERE NOT EXISTS (
  66. SELECT *
  67. FROM muk_groups_complete_%s_rel r
  68. WHERE r.aid = a.id
  69. );
  70. ''' % (self._table, model)
  71. self.env.cr.execute(sql)
  72. fetch = self.env.cr.fetchall()
  73. return len(fetch) > 0 and list(map(lambda x: x[0], fetch)) or []
  74. else:
  75. return []
  76. @api.model
  77. def _get_access_ids(self):
  78. base, model = self._name.split(".")
  79. sql = '''
  80. SELECT r.aid
  81. FROM muk_groups_complete_%s_rel r
  82. JOIN muk_security_groups g ON r.gid = g.id
  83. JOIN muk_groups_users_rel u ON r.gid = u.gid
  84. WHERE u.uid = %s AND g.perm_read = true
  85. ''' % (model, self.env.user.id)
  86. self.env.cr.execute(sql)
  87. fetch = self.env.cr.fetchall()
  88. access_ids = len(fetch) > 0 and list(map(lambda x: x[0], fetch)) or []
  89. return access_ids
  90. @api.model
  91. def _get_complete_access_ids(self):
  92. return self._get_no_access_ids() + self._get_access_ids()
  93. @api.multi
  94. def _eval_access_skip(self):
  95. return False
  96. @api.multi
  97. def check_access_rule(self, operation):
  98. super(BaseModelAccessGroups, self).check_access_rule(operation)
  99. if self.env.user.id == SUPERUSER_ID or self._eval_access_skip():
  100. return None
  101. base, model = self._name.split(".")
  102. no_access_ids = self._get_no_access_ids()
  103. for record in self.filtered(lambda rec: rec.id not in no_access_ids):
  104. sql = '''
  105. SELECT perm_%s
  106. FROM muk_groups_complete_%s_rel r
  107. JOIN muk_security_groups g ON g.id = r.gid
  108. JOIN muk_groups_users_rel u ON u.gid = g.id
  109. WHERE r.aid = %s AND u.uid = %s
  110. ''' % (operation, model, record.id, self.env.user.id)
  111. self.env.cr.execute(sql)
  112. fetch = self.env.cr.fetchall()
  113. if not any(list(map(lambda x: x[0], fetch))):
  114. raise AccessError(_("This operation is forbidden!"))
  115. #----------------------------------------------------------
  116. # Read
  117. #----------------------------------------------------------
  118. def _after_read(self, result, *largs, **kwargs):
  119. result = super(BaseModelAccessGroups, self)._after_read(result)
  120. if self.env.user.id == SUPERUSER_ID or self._eval_access_skip():
  121. return result
  122. access_ids = self._get_complete_access_ids()
  123. result = [result] if not isinstance(result, list) else result
  124. if len(access_ids) > 0:
  125. access_result = []
  126. for record in result:
  127. if record['id'] in access_ids:
  128. access_result.append(record)
  129. return access_result
  130. return []
  131. def _after_search(self, result, *largs, **kwargs):
  132. result = super(BaseModelAccessGroups, self)._after_search(result)
  133. if self.env.user.id == SUPERUSER_ID or self._eval_access_skip():
  134. return result
  135. access_ids = self._get_complete_access_ids()
  136. if len(access_ids) > 0:
  137. access_result = self.env[self._name]
  138. if isinstance(result, int):
  139. if result in access_ids:
  140. return result
  141. else:
  142. for record in result:
  143. if record.id in access_ids:
  144. access_result += record
  145. return access_result
  146. return self.env[self._name]
  147. def _after_name_search(self, result, *largs, **kwargs):
  148. result = super(BaseModelAccessGroups, self)._after_name_search(result)
  149. if self.env.user.id == SUPERUSER_ID or self._eval_access_skip():
  150. return result
  151. access_ids = self._get_complete_access_ids()
  152. if len(access_ids) > 0:
  153. access_result = []
  154. for tuple in result:
  155. if tuple[0] in access_ids:
  156. access_result.append(tuple)
  157. return access_result
  158. return []
  159. #----------------------------------------------------------
  160. # Read, View
  161. #----------------------------------------------------------
  162. def _compute_groups(self, write=True):
  163. if write:
  164. for record in self:
  165. record.complete_groups = record.groups
  166. else:
  167. self.ensure_one()
  168. return {'complete_groups': [(6, 0, self.groups.mapped('id'))]}