ir_attachment.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. # -*- coding: utf-8 -*-
  2. # Part of Odoo. See LICENSE file for full copyright and licensing details.
  3. from odoo import _, models, SUPERUSER_ID
  4. from odoo.exceptions import AccessError, MissingError, UserError
  5. from odoo.http import request
  6. from odoo.tools import consteq
  7. class IrAttachment(models.Model):
  8. _inherit = 'ir.attachment'
  9. def _check_attachments_access(self, attachment_tokens):
  10. """This method relies on access rules/rights and therefore it should not be called from a sudo env."""
  11. self = self.sudo(False)
  12. attachment_tokens = attachment_tokens or ([None] * len(self))
  13. if len(attachment_tokens) != len(self):
  14. raise UserError(_("An access token must be provided for each attachment."))
  15. for attachment, access_token in zip(self, attachment_tokens):
  16. try:
  17. attachment_sudo = attachment.with_user(SUPERUSER_ID).exists()
  18. if not attachment_sudo:
  19. raise MissingError(_("The attachment %s does not exist.", attachment.id))
  20. try:
  21. attachment.check('write')
  22. except AccessError:
  23. if not access_token or not attachment_sudo.access_token or not consteq(attachment_sudo.access_token, access_token):
  24. message_sudo = self.env['mail.message'].sudo().search([('attachment_ids', 'in', attachment_sudo.ids)], limit=1)
  25. if not message_sudo or not message_sudo.is_current_user_or_guest_author:
  26. raise
  27. except (AccessError, MissingError):
  28. raise UserError(_("The attachment %s does not exist or you do not have the rights to access it.", attachment.id))
  29. def _post_add_create(self):
  30. """ Overrides behaviour when the attachment is created through the controller
  31. """
  32. super(IrAttachment, self)._post_add_create()
  33. for record in self:
  34. record.register_as_main_attachment(force=False)
  35. def register_as_main_attachment(self, force=True):
  36. """ Registers this attachment as the main one of the model it is
  37. attached to.
  38. """
  39. self.ensure_one()
  40. if not self.res_model:
  41. return
  42. related_record = self.env[self.res_model].browse(self.res_id)
  43. if not related_record.check_access_rights('write', raise_exception=False):
  44. return
  45. # message_main_attachment_id field can be empty, that's why we compare to False;
  46. # we are just checking that it exists on the model before writing it
  47. if related_record and hasattr(related_record, 'message_main_attachment_id'):
  48. if force or not related_record.message_main_attachment_id:
  49. #Ignore AccessError, if you don't have access to modify the document
  50. #Just don't set the value
  51. try:
  52. related_record.message_main_attachment_id = self
  53. except AccessError:
  54. pass
  55. def _delete_and_notify(self):
  56. for attachment in self:
  57. if attachment.res_model == 'mail.channel' and attachment.res_id:
  58. target = self.env['mail.channel'].browse(attachment.res_id)
  59. else:
  60. target = self.env.user.partner_id
  61. self.env['bus.bus']._sendone(target, 'ir.attachment/delete', {
  62. 'id': attachment.id,
  63. })
  64. self.unlink()
  65. def _attachment_format(self, legacy=False):
  66. safari = request and request.httprequest.user_agent and request.httprequest.user_agent.browser == 'safari'
  67. res_list = []
  68. for attachment in self:
  69. res = {
  70. 'checksum': attachment.checksum,
  71. 'id': attachment.id,
  72. 'filename': attachment.name,
  73. 'name': attachment.name,
  74. 'mimetype': 'application/octet-stream' if safari and attachment.mimetype and 'video' in attachment.mimetype else attachment.mimetype,
  75. }
  76. if not legacy:
  77. res['originThread'] = [('insert', {
  78. 'id': attachment.res_id,
  79. 'model': attachment.res_model,
  80. })]
  81. else:
  82. res.update({
  83. 'res_id': attachment.res_id,
  84. 'res_model': attachment.res_model,
  85. })
  86. res_list.append(res)
  87. return res_list