Skip to content
Snippets Groups Projects
Commit 46f2e191 authored by Nicolas Lempereur's avatar Nicolas Lempereur
Browse files

[FIX] base: access_token error handling correctly


When an attachment is requested with an access_token, a server error
would occur in some situation.

With this changeset when an access token is specified:

- returns a 404 error if the attachment does not exist
- returns a 403 error if the attachment has no access_token

Without this change, the added test would fail with:

```
 status = test_access(access_token='Secret')
 self.assertEqual(status, 403,
     "no access if access token for attachment without access token")
 | if not consteq(obj.access_token, access_token):
 | TypeError: unsupported operand types(s) or combination of types: 'bool' and 'str'

 status = test_access(access_token='Secret')
 self.assertEqual(status, 404,
     "no access with access token for deleted attachment")
 | if not consteq(obj.access_token, access_token):
 | odoo.exceptions.MissingError: ('Record does not exist or has been deleted.', None)
```

close #26647
opw-1884419
closes #27275

Co-authored-by: default avatarWolfgang Taferner <wtaferner@users.noreply.github.com>
parent 2a697f1c
Branches
Tags
No related merge requests found
......@@ -278,10 +278,6 @@ class IrHttp(models.AbstractModel):
obj = None
if xmlid:
obj = env.ref(xmlid, False)
elif id and model == 'ir.attachment' and access_token:
obj = env[model].sudo().browse(int(id))
if not consteq(obj.access_token, access_token):
return (403, [], None)
elif id and model in env.registry:
obj = env[model].browse(int(id))
......@@ -289,6 +285,12 @@ class IrHttp(models.AbstractModel):
if not obj or not obj.exists() or field not in obj:
return (404, [], None)
# access token grant access
if model == 'ir.attachment' and access_token:
obj = obj.sudo()
if not consteq(obj.access_token or '', access_token):
return (403, [], None)
# check read access
try:
last_update = obj['__last_update']
......
......@@ -79,3 +79,54 @@ class test_ir_http_mimetype(common.TransactionCase):
)
mimetype = dict(headers).get('Content-Type')
self.assertEqual(mimetype, 'image/gif')
def test_ir_http_attachment_access(self):
""" Test attachment access with and without access token """
public_user = self.env.ref('base.public_user')
attachment = self.env['ir.attachment'].create({
'datas': GIF,
'name': 'Test valid access token with image',
'datas_fname': 'image.gif'
})
defaults = {
'id': attachment.id,
'default_mimetype': 'image/gif',
'env': public_user.sudo(public_user.id).env,
}
def test_access(**kwargs):
status, _, _ = self.env['ir.http'].binary_content(
**defaults, **kwargs
)
return status
status = test_access()
self.assertEqual(status, 403, "no access")
status = test_access(access_token='Secret')
self.assertEqual(status, 403,
"no access if access token for attachment without access token")
attachment.access_token = 'Secret'
status = test_access(access_token='Secret')
self.assertEqual(status, 200, "access for correct access token")
status = test_access(access_token='Wrong')
self.assertEqual(status, 403, "no access for wrong access token")
attachment.public = True
status = test_access()
self.assertEqual(status, 200, "access for attachment with access")
status = test_access(access_token='Wrong')
self.assertEqual(status, 403,
"no access for wrong access token for attachment with access")
attachment.unlink()
status = test_access()
self.assertEqual(status, 404, "no access for deleted attachment")
status = test_access(access_token='Secret')
self.assertEqual(status, 404,
"no access with access token for deleted attachment")
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment