-
-
Notifications
You must be signed in to change notification settings - Fork 5.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clipper: Increase protection of files downloaded by webclipper and cloudRestrict download media file #9676
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Pedro, that looks good. I've just left a few comments regarding the test units.
Also please could you fix the pull request title?
@@ -78,4 +78,44 @@ describe('routes/notes', () => { | |||
|
|||
expect(response).toBe(''); | |||
}); | |||
|
|||
test('should not copy content from invalid protocls', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
protocls => protocols
const shimFsDriverCopySpy = jest.fn(); | ||
jest.spyOn(shim, 'fsDriver').mockImplementation(() => { | ||
return { | ||
copy: shimFsDriverCopySpy, | ||
} as any; | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer if we avoid using spy
as much as possible because it tests implementation details, and the more we do this the harder it becomes to refactor the code. For example if we start using fs-extra
instead of fsDriver
this test would be broken but there's no reason for that to happen since the input/output of the function hasn't changed.
In that particular case, isn't it possible to verify that the function simply did nothing (didn't download any media file)?
jest.spyOn(shim, 'fetchBlob').mockImplementation(() => { | ||
return { | ||
headers: { | ||
'content-type': 'image/jpg', | ||
}, | ||
}; | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess it makes sense to mock fetchBlob
to avoid http requests in tests, but for the other mocks I'm not sure, I think they can be avoided. It's nice to know in advance the UUID but again if we use another uuid lib, this test will be broken. Maybe you can check what's in the directory before and after to find what you need.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is trickier to do without spyOn.
What I'm testing is when the image type can't be found by the URL.
We fetch the image and save it on filesystem with fetchBlob
function, since we don't want a HTTP request in the test I'm using a mock for it, so no file gets created. Then the code will call tryToGuessExtFromMimeType
, since the URLs that I used for the test don't have an extension, which will try to move the file that was never created (that is why I have a mock for shim.fsDriver.move
)
In the end we can't even look at the temp directory to see if the test worked because no files has ever been created in this test. Maybe it would be best to remove this test altogether?
@pedr, another issues with
I don't understand why because you've added |
I didn't notice this problem. This was probably one of the reasons that I choose to use mock so much, since I couldn't use the I rewrote some tests to remove some mocks and use the |
jest.spyOn(shim, 'fetchBlob').mockImplementation(fetchBlobSpy); | ||
jest.spyOn(uuid, 'create').mockReturnValue('mocked_uuid_value'); | ||
const spy1 = jest.spyOn(shim, 'fetchBlob').mockImplementation(fetchBlobSpy); | ||
const spy2 = jest.spyOn(uuid, 'create').mockReturnValue('mocked_uuid_value'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's necessary to mock uuid.create - you can simply check that "some file" exists. You can also check the file content to verify it's the right file. fetchBlob
makes more sense
const shimFsDriverMoveSpy = jest.fn(); | ||
const spy2 = jest.spyOn(shim, 'fsDriver').mockImplementation(() => { | ||
return { | ||
move: shimFsDriverMoveSpy, | ||
} as any; | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The spy shouldn't be needed since you're mocking fetchBlob and can make it create real files?
Hi, I think now it is closer to your vision. At first, I thought that creating a file inside fetchBlob would be weird for the test, but since it is pretty simple and makes the test more meaningful I think it is the correct choice. Ready for review again. |
I'm changing the current behavior from
downloadMediaFile
from ainvalidProtocols
list to anallowedProtocols
list, which havehttp
,https
,data
andfile
as the default values.I also added more automated tests to the
downloadMediaFile
function and refactored the code to be more readable, basically grouping things together in functions.I think the best way to read this PR is by looking at each individual commit.