Fixes #2659 - Make console logs in browser configuration details easier to read#3103
Fixes #2659 - Make console logs in browser configuration details easier to read#3103
Conversation
webcompat/api/console_logs.py
Outdated
|
|
||
| from webcompat import app | ||
|
|
||
| console_logs = Blueprint('console_logs', __name__, url_prefix='/console_logs') |
There was a problem hiding this comment.
I'm not sure I have a super strong opinion, but is there a reason you didn't just add support for uploading JSON content in the /uploads route? What are the advantages of having a new route to handle uploads of a different kind of file type?
There was a problem hiding this comment.
I agree. We should probably make the code versatile enough so that it can handle images and json.So it would be probably better to have the uploads route (blueprint) to behave differently with the content-type. So depending on the Content-Type, there is a validation process depending probably on the content of the file, size, etc. Like we do already for images.
There was a problem hiding this comment.
Thanks for the feedback. I've moved console log saving to uploads blueprint, could you please take another look @miketaylr @karlcow
webcompat/api/console_logs.py
Outdated
|
|
||
| from webcompat import app | ||
|
|
||
| console_logs = Blueprint('console_logs', __name__, url_prefix='/console_logs') |
There was a problem hiding this comment.
I agree. We should probably make the code versatile enough so that it can handle images and json.So it would be probably better to have the uploads route (blueprint) to behave differently with the content-type. So depending on the Content-Type, there is a validation process depending probably on the content of the file, size, etc. Like we do already for images.
tests/unit/test_urls.py
Outdated
|
|
||
| def test_console_logs(self): | ||
| """Test that /console_logs exists.""" | ||
| rv = self.app.get('/console_logs/11/20/1c0a7174-2c15-480f-9cee-e6183e6a781b') # noqa |
There was a problem hiding this comment.
note to self, we probably needs to create a console_logs directory
|
🎈 I'll deploy this to staging so we can play around with it. (before merging) |
|
@ksy36 I filed a test issue on staging: |
so that's what I wanted to check but @miketaylr beat me to it. Cool! webcompat.com/webcompat/helpers.py Lines 766 to 774 in e12e205 Instead of True, False here the function should probably report a type, be Image or JSON (These could be strings). To return this specific type we need to validate it, the validation criteria needs to make it clear what we accept or not. Then there is the question that @miketaylr was pointing about sanitization. server side or client side? |
For both of them validation happens later on, in their corresponding classes after an instance is created and before saving attempt. I wanted to separate these two paths (image/json) and have related methods contained within their classes. So And validation we have these: For image (existing validation): webcompat.com/webcompat/api/uploads.py Lines 68 to 86 in e12e205 For json, it just checks that passed string is a valid JSON webcompat.com/webcompat/api/uploads.py Lines 149 to 153 in e12e205 Maybe we could use something like https://python-jsonschema.readthedocs.io/en/latest/ to validate json schema. What do you think @karlcow ? |
|
For sanitization part, @miketaylr mentioned https://api.jquery.com/text/ will escape HTML tags. So I've tried it and it works ok, I'll test it a bit more :) |
Good idea.
So for images we try to convert to a Pillow Object (and Pillow handles the validation by raising TypeError if it doesn't work) Probably we should rename the Thanks a lot @ksy36 |
|
So I'm thinking maybe a safer way for sanitization is to escape html tags before saving to the server. That way we don't have malicious code uploaded (in theory :)). I've tried this and it seems to be working good given that the structure of json we get from the reporter is consistent: import html
....
def process_json(self, data):
try:
d = json.loads(data)
new_set = []
for item in d:
new_dict = {}
for key, value in item.items():
if isinstance(value, list):
new_dict[key] = ', '.join(list(map(lambda x: html.escape(x), value)))
else:
new_dict[key] = html.escape(value)
new_set.append(new_dict)
return new_set
except ValueError:
abort(400)So it converts strings like this
To be: This involves some extra processing on the python side though. Do you have any thoughts on this @karlcow @miketaylr ? |
|
I agree escaping before we save to disk is a better idea - we don't want to accidentally regress the client side escape... I found the following answer on stackoverflow: https://stackoverflow.com/a/27382959 Which points to Can we just use that instead of |
|
Moving json rendering to the server (with jinja) helped with sanitization. So a <script> element, for example, is returned as |


r? @karlcow @miketaylr