I want to check in a patch to file.php (and filelib) which allows modules to control file requests (so that a file request goes 'via' the module). The main goal of this patch is so that modules can prevent certain files within their moddata area from being accessible to anyone on that course, but it achieves a few other things too and I think it's a decent change that fits within the current way Moodle works and makes a genuine improvement.
It should have absolutely no impact on any existing code, core or addon, except:
- Any code that previously referred to URLs like the following: file.php/3/!via/... (where 3 is a course code) will stop working. I am pretty sure there won't be any such code.
- Requests for file.php/3/moddata/somemodule/whatever will take fractionally longer as it requires somemodule/lib.php for that now. (It only needs this for a function_exists check; could be cached if it ever becomes a performance problem.)
The change was previously discussed here - http://moodle.org/mod/forum/discuss.php?d=37878 - but I have modified it to take note of Eloy's security concerns. Eloy's other issue was that really this whole area of the system sucks and should be redesigned properly - he's right, but given the principles of incremental change that we were told were so important, and also the practicality that we'd like to have this in now, I feel this is a good change in the meantime.
Basically what this change achieves is the following:
- If a frog_process_file_request function exists, then trying to access file.php/13/moddata/frog/anything will give an error (in other words, once a module uses this mechanism, its files are prevented from direct access).
- Accessing file.php/13/!via/frog/anything will result in a call to the frog_process_file_request function, which will be passed the value of 'anything' and the course number, and can return the full path of a file which the user should be allowed to download, or false if they shouldn't.
- The return from this function is further checked and modules are only allowed to return:
- Files that are within the requested course, but are not within moddata (thus preventing access to data of other modules).
- Files that are within moddata/thismodule on any course.
- Files that are within dataroot/moddata/thismodule.
- Files that are within the requested course, but are not within moddata (thus preventing access to data of other modules).
By the way, this code is required by the resourcepage module which we'll be using here, as it provides security on file downloads (e.g. if a file is set to only display on a certain date, you can't DL it before, even if you guess the filename). We hope to release the resourcepage module code for public use if anyone else wants it - so I'm trying to review my core changes and get them in now, in order that installing resourcepage doesn't involve running a whole bunch of patches first... This is the largest, I think.
--sam