Re: Simple API proposal for writing file in local file system

Hi Jeremie,

Have you seen this proposal? 
<http://lists.w3.org/Archives/Public/public-script-coord/2013JulSep/0379.html> 
  It's not clear to me if your proposal here is trying to solve problems 
that the above proposal doesn't already solve...

Cheers,
Ehsan

On 2013-10-18 8:07 AM, Jeremie Patonnier wrote:
> Hello!
>
> As a Web developer, I recently dig into the proposed FileSystem API [1]
> which cover many use cases except one: How a user can actually allows a web
> application to really write something in the user local file system (even
> if it's slow). On the other hand, the File API: Writer [2] cover that need
> but with a very overwelming interface which make very hard to use for
> simple open/save operation.
>
> There are well known workaround but we could make the life of web developer
> easier by providing a simple convenient and secure interface to do this.
>
>
> *# Accessing a file.*
>
> Currently, as per the File API [3], the only way to access a file in the
> user file system is by using the <input type="file"> element. For some
> reason, web developer don't want to expose such input to the user
> (basically, because it's impossible to change its look and feel
> consistently across browsers). To work around this, they hide it and
> perform a fake click on it to prompt the user to pick some files.
>
> We could provide a method that allow to do the same. In terms of security,
> it would also make easier to track malicious attempt to acces the file
> system as we will be able to monitor all access through that single method.
>
> partial interface Navigator {
>    Promise openFile();
> }
>
> In case of success, the Promise will get a FileList object as the user can
> pick more than one file.
>
>
> *# Writing a file*
>
> Currently, the only way to write a file on the user file system is to turn
> a File object into a data URI with the MIME type application/octet-stream
> in order to force a download of the file. This allows the user to save the
> file wherever he wants on his device.
>
> This is very rough and have two drawbacks:
>
>     1. if the user has setup his browser to always put downloaded file in a
>     given repository, it could require some extra action from the user to move
>     the file in his file system. This lead to a bad user experience that many
>     web developers wish to avoid.
>     2. if the user has previously open the file that need to be put back in
>     his file system, it's impossible to perform a silent writing. The user is
>     always prompt to perform the overriding itself. Once again, it's a bad user
>     experience that web developers wish to avoid.
>
> To solve those two issues, we could provide a save method that will allow
> to bypass any download setup and to provide a secure way of making silent
> writing.
>
> Note: It is worth noticing that Microsoft did something similare for IE11
> with the msSaveBlob [4] and msSaveOrOpenBlob [5] methods
>
> partial interface Navigator {
>    Promise saveFile(File file, optional boolean silent);
> }
>
> Note: it would be possible to add some events to keep track of the writing
> operation, but Promise are good enough as we just want to save files in the
> local file system rather than making some intensive IO operation. If a web
> developer want to do that it would be better for him to relay on the
> FileSystem API.
>
> Making secured silent writing require two things:
>
> 1. Only file picked by the user and explicitely chose as writable by him
> can be silently writen. The LockedFile object in the FileSystem API draft
> is close to that but looks unnecessary complicated. I suggest to make
> something simple by extending the File interface.
>
> partial interface File {
>    readonly attribute DOMString? mode; // It can be 'readonly' or 'writable'
>    readonly attribute boolean? lock; // If true, only that tab can modify
> the file
> }
>
> In order to sustain this, the 'mode' and 'lock' must be set when calling
> the openFile method:
>
> partial interface Navigator {
>    Promise openFile(optional DOMString mode, optional boolean lock);
> }
>
>     - The 'mode' indicate if the File is 'readonly' or 'writable'. The
>     browser must retain the information of the location in the file system for
>     all writable files object, but this information will never be exposed to
>     web content.
>     - The 'lock' indicate if the browser must put a lock on the file,
>     allowing only the tab which access it first to write back into the file
>     (It's an internal lock maintain by the browser, it is never put at the file
>     system level, I'm not sure but I think there are to many side effects to
>     allow such a hard lock). If another tab has already put a lock on the file,
>     the Promise will fail with an appropriate error message. The lock is
>     released when the File object is destroyed (it is garbage collected, the
>     tab using it is shutdown, etc.). Note: it could be convenient to have a
>     setLock method to change the lock state.
>
> If a File object is created without using the openFile method, the mode and
> lock will be null;
>
> The saving steps should be the following:
>
>     1. If a File object is saved using the saveFile method:
>        1. If the object has its mode set to 'readonly' or null
>           1. The user is prompt to choose where to save the file
>        2. If the object has its mode set to 'writable'
>        1. If the silent parameter is set to true
>              1. if the file is no longer available in the file system
>                 1. If the object has its lock set to true
>                    1. The file is recreated using the data available in the
>                    File object
>                 2. If the object has its lock set to false
>                    1. The user is prompt to choose where to save the file
>                 2. otherwise
>                 1. The file on the file system is silently overridden by the
>                 content of the File object
>              2. If the silent parameter is set to false
>              1. if the file is no longer available in the file system
>                 1. The user is prompt to choose where to save the file
>              2. Otherwise
>                 1. The user is prompt to allow the override
>
> 2. The first time a silent saving is performed, the user must be prompt to
> allow this (possible answer are never, this time only, for the rest of the
> session, or forever); If the user chose 'never', any call to the saveFile
> method will be done as if the silent parameter were set to false (whatever
> its true value).
>
> In order to avoid nasty security issues, the calls to the saveFile method
> from script hosted on third party domain should never be allowed to be
> silent and each saving prompt should display which domain is trying to
> write on the file system.
>
> [1] http://w3c.github.io/filesystem-api/Overview.html
> [2] http://dev.w3.org/2009/dap/file-system/file-writer.html
> [3] http://dev.w3.org/2006/webapi/FileAPI/
> [4] http://msdn.microsoft.com/en-us/library/hh772331%28v=vs.85%29.aspx
> [5] http://msdn.microsoft.com/en-us/library/hh772332%28v=vs.85%29.aspx
>
> Best,
>

Received on Friday, 18 October 2013 17:30:27 UTC