[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: Wolfgang Taferner <wtaferner@users.noreply.github.com>
This commit is contained in:
co-authored by
Wolfgang Taferner
parent
2a697f1c5b
commit
46f2e1918f
@@ -278,10 +278,6 @@ class IrHttp(models.AbstractModel):
|
|||||||
obj = None
|
obj = None
|
||||||
if xmlid:
|
if xmlid:
|
||||||
obj = env.ref(xmlid, False)
|
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:
|
elif id and model in env.registry:
|
||||||
obj = env[model].browse(int(id))
|
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:
|
if not obj or not obj.exists() or field not in obj:
|
||||||
return (404, [], None)
|
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
|
# check read access
|
||||||
try:
|
try:
|
||||||
last_update = obj['__last_update']
|
last_update = obj['__last_update']
|
||||||
|
|||||||
@@ -79,3 +79,54 @@ class test_ir_http_mimetype(common.TransactionCase):
|
|||||||
)
|
)
|
||||||
mimetype = dict(headers).get('Content-Type')
|
mimetype = dict(headers).get('Content-Type')
|
||||||
self.assertEqual(mimetype, 'image/gif')
|
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")
|
||||||
|
|||||||
Reference in New Issue
Block a user