-
Notifications
You must be signed in to change notification settings - Fork 135
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
Add Imageproxy to resolve relative Imagepaths #785
Conversation
fd5d47f
to
33bc254
Compare
I added a prototype toolbar for image-uploading. It is barebones, and needs to be improved upon before release, do we want to add additional buttons, similar to how nextcloud/text has one? in that case i would just hide the toolbar in this pull request, and start working on a proper toolbar after this PR with proper styling and icons. |
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.
Could you please add an API documentation to https://github.com/nextcloud/notes/blob/master/docs/api/v1.md ? 🙂
@stefan-niedermann Yes, but i would like to wait for a review of those api-endpoints. I am really not sure if i implemented them in a good way, especially about the |
Nice, that's very cool! Thank you very much for digging into this! I'm very sorry, that I wasn't able to review this, yet. I will do my very best in order to have a deep look on the weekend! |
@korelstar No problem! It's a bit offtopic, but what do you think about this toolbar idea? The styling is not good at the moment, and some icons are missing, but i think the general idea is not to bad maybe we should try to mirror what nextcloud text does: while it is a really bad idea to copy their markdown editor, i think their ui is very clean |
@korelstar Could you give me a hint on how i rebuild the css outside of vue files? I'd lile to add icons but they don't seem to update |
I have problems with relative subdirectories and the ../ notation. My current idea is to try using base64 encoding, that should get rid of the character issues while easily usable on almost every system that may want to access the api. |
base64 encoding works well. Also we need to find out if and how we allow both of the picker, local filesystem and the nextcloud one |
Thank you very much for your efforts, @newhinton ! I like your approach and I think it's on a good way. It looks that there are some fundamental question to answer resp. decisions to be made. Let's try to collect them. How to identify an attachmentYou've chosen the file name for identifying the attachment. That's a good, straight forward approach. However, I see one problem: if you add an attachment to your note and then change the note's category, the attachment won't be found anymore. Since I think that's a common use case, we have to find a solution for this. Source of attachmentsShould we allow to attach files to a note from the notes path only or should we allow files from the whole Nextcloud's user path? You've switched to the notes path only for security reasons. I think this is a wise decision, but I want to make this decision clear. API pathWhat about the following in order to eliminate the ToolbarA toolbar is a good enhancement, let's discuss details in your new issue #788. Static CSS
If you change the scss files in the |
Could you clarify what you mean with attachment id? My assumption was that we can only deal with standard "URL's". Those can be relative or absolute, where absolute links are already handled properly. So we have relative path's which usually point to a local filesystem. So i wanted to resolve this without needing a "new" way to integrate images, as to keep compatibility with other notes apps. Where would we get an attachement id, and how would we store it? to your point with |
I will also remove the toolbar in my cleanup before final commit. It is basically necessary as long as we test/change this code, but the ability to upload files (from the ui) should be included with the toolbar, not this PR |
Oh and regarding the issue with switching the category: do other apps take care of this? Should we? One could argue that it is not our job to take care of that, since other notes could also rely on the image beeing in that folder. If we move it, we could break other notes aswell. The same argument can be made for deleting images from the source folder. |
Attachment id would be the Nextcloud file id of that attachment. But I see your point, such a syntax would not be compatible to other apps. Honestly, I don't know if other apps handle the movement scenario. Maybe, they don't, too. Just wanted to list all issues/decisions that we make, to be clear that we are aware of them. Regarding the |
Oh yeah, i tried it without declaring it and it works flawless. ...i also found the documentation for it: 😀 i will change it to use parameters instead of base64, it is way more intuitive and readable. However, one thing: we only render images currently, not other content, so "attachment" is not 100% accurate at the moment. We may implement a "download" button for filetypes that we do not recognize in the renderer at a later point. Though, i like the idea! |
Yes, this should be compatible for future enhancements. |
I think i am now ready for a final review. I have refactored a lot and changed naming quite a bit, so it should be way better now. (also the toolbar is gone, but the actual upload/selection functions are still there, they can be easily integrated later) |
Oh i remembered something: is this the right way to query the current category? notes/src/components/EditorEasyMDE.vue Line 136 in 9f0266c
i found that it does not work reliable, so this may still be broken in my pr. Also, is there a discussion on why we call it category and not folder? |
This should be fine. What do you mean exactly with "does not work reliable"? What happens?
It's our application abstraction layer. For the user, a note is assigned to a category. On the technical backend, a note is stored as a file and the category is stored as folder. But those are different layers. The user does not need to know this. The user is only interested in notes and categories - not in files and folders.
I like this!
Could you please fix that conflict (and rebase your PR)? I will do a deeper review later this day. |
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 finally found some time for a deep review :-)
First of all: thank you again for your work on this! I'm writing some general remarks and I did commented some special changes.
Code style
Please use make lint
for checking your code style and fix all errors and warnings regarding your changes.
external API
Currently, you've implemented the internal API (NotesController
). That's fine and sufficient for now. However, you've documented the external API (docs/api/v1.md
) although it is not implemented yet. I think we can postpone this for the next step. Since you're developing very fast and you have opened multiple PRs that are partly conflicting, let's concentrate on small parts.
Controller vs. Service
That controllers are used to connect routes with app logic. But please note, that the actual app logic should be in respective service classes. On the other hand, the service should not contain any code regarding the provided API (e.g. Http
stuff), this has to be done in the controller.
To be more concrete: please move most of the method NotesController.getAttachment
(except the Response
stuff) to NotesService
and move the Response
stuff from NotesService.createImage
to NotesController
.
lib/Controller/NotesController.php
Outdated
// calculate how many parentnodes we need to get 'up' | ||
$parentcount = substr_count($path, '../'); | ||
$path = str_replace("../", "", $path); | ||
|
||
$relativeImageNode = $this->root->get($notePath); | ||
for ($i = 0; $i < $parentcount; $i++) { | ||
$relativeImageNode = $relativeImageNode->getParent(); | ||
} | ||
$targetimage = $this->root->get($relativeImageNode->getPath()."/".$path); |
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.
There must be a check, if we are still in the notes path. Currently, I can load images from other users!
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.
ohh yeah, just to understand how you accessed this:
did you prepend '../' the exact same amount to logically get back to "root"? and then append a full, internal nextcloud-path including the different user?
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.
Yes
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.
Could you provide me with your testsetup?
I know why and how to fix it, but i cannot replicate it since i always get a second / in my path
Eg.: ?path=../../../test/files/Nextcloud Manual.pdf
results in an exception to be thrown, not an image to be served.
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 think i fixed it, but since i could not properly reproduce it i cant really verify it. Please try to break it again! I want to be sure this cannot be abused
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.
My test setup:
User A
has a note in notes/test/test.md
with the following content:
![Attack](../../../../B/files/DSC_0020.jpg)
User B
has the image file DSC_0020.jpg
in his user directory.
I will test your changes soon.
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, looks like your fix is working. I think your solution on how to fix this is a good approach! 👍
@korelstar did you mean the DCO? |
No, I mean the warnings from |
Signed-off-by: Felix Nüsse <felix.nuesse@t-online.de>
Interesting that they did not show up in the testruns. Anyway, i fixed them except those i did not cause, and a single one i dont know how to fix: The file we are serving is actually not a |
This can be done by inserting I added this and I also did some of the major remarks from #785 (review) . Will continue with reviewing later. |
@korelstar Actually i do have a question regarding my changes to the readme. Since the imageproxy is available through an endpoint, doesn't that count as an external api? Why should it not be documented? |
The notes app has two REST interfaces: one for the web interface ( In your current implementation, the proxy is not available from external, since it uses the Of course, the goal is to provide this new feature also to the external API. But let's do this in a separate PR, so we can merge this PR earlier and do further tests with it. Another point: when changing the external API, you will have to write respective tests. This is currently missing. |
Just did some last improvements. If you agree, I will merge this now. |
The simplification looks good to me, except i cant see how we make sure we did not leave the notes directory. Was the removal of the last if clause wether the resulting node is still in the notes-path intentional? Edit: I think i figured it out, you do not actually work on a full path, but only on the categories of a note. So when we "overstep" the boundaries we get 'nothing' (in terms of the array you are using) and then we get the child of the notes folder with that array |
Exactly! |
Next steps are: 1. Add upload feature to web-frontendImplement using toolbar (requires #790) or at the first step with a new entry in the three-dot menu. I vote for the last since we don't have any dependencies, then. Would you like to work on this? 2. Public API for third-party apps
|
@korelstar would you mark #74 as resolved? I'd like to claim the bounty for the ticket but i dont think its my place to close the ticket on my own for that |
oh and i will continue work on the toolbar aswell, though that might take a couple of weeks |
I don't think that it's already solved. But you're on a good way! A big part of that issue is about uploading a new image. You've already prepared this, but it's currently not usable. The original issue's requirements for uploading are here: #74 (comment) . In addition, you could add an upload menu item (see #785 (comment)). |
Todo, for now see #74
allow arbitrary files to be linked, not only images(This is not really supported by markdown afaik)maybe add error-image to display anything at all when image not resolvable(not the job of the service)We should have a serious discussion about the proxy. Currently it allows to get ALL files from files, even outside of the Notes-folder. We may want to restrict access to Files somewhere accessible to the notes app, not all over the instance.Currently only files in the Notes-basefolder are accessible. This removes all security issues posed by allowing abitrary paths.
Also, because of how urls are encoded,
../
is beeing removed (from the url). Therefore, the api only accepts;;/
as a substitute, and all clients need to replace the../
syntax before rendering the link (i am open for suggestions on how to fix this). The markdown-sourcefile does not need to be modified, and is not beeing modified by this.