Central File Storage
====================
Uranium provides a central file storage location where its plug-ins can store files and directories. They can move a file or folder into the central file storage, give it a name and version number, and then retrieve the file again when it needs to be used. The central file storage is neutral for all versions of the application. It is not located in the folders specific to one version of the application, but in a place where all versions can access it.

Purpose
-------
When upgrading the application to a new version, the user's configuration is copied to a new folder and upgraded there. This configuration not only contains preferences and profiles, but also the plug-ins the user had installed. If these plug-ins contain large files, those would normally get copied every time the user installs a new version of the application. This can take up a significant amount of space on the hard drive.

Using the central file storage, the plug-in can store big files in a location that doesn't get copied when a new version is installed. This can save a significant amount of hard drive space for the user.

How To Store Files
------------------
To mark files for storing centrally, create a JSON file in the root directory of the plug-in (next to `plugin.json`), called `central_storage.json`. This JSON file gets the following format:

```
[
    ["some_file.txt", "some file", "1.0.0", "ABCDEF0123456789"],
    ["subdir/another_file.txt", "another file", "1.1.0", "9876543210FEDCBA"],
    ["big_directory", "resource directory", "1.0.0", "ABABCDCDEFEF0123"],
    ...
]
```

The JSON contains a list of the files and directories that need to be stored centrally. Each entry of the list is itself a list with four entries:
* The path to the file to store, relative to the JSON file.
* A name to identify the file by. This serves as a unique identifier to retrieve the correct file when it's needed.
* A semantic version number for the file. Multiple versions of the same file can be stored, so that the name doesn't need to change if a later version of the plug-in updates the file.
* A SHA256 hash of the file or directory. This can be generated by any SHA256 hash generator. In the case of a folder, all files in the folder need to be enumerated alphabetically and their hashes appended end-to-end. That string itself is then hashed again with SHA256.

The central file storage will then make sure that those files get moved upon first registering the plug-in, while making sure that any signed plug-ins still remain valid.

In addition, the `CentralFileStorage.store(...)` function can be used to programmatically store files. This can be useful if the plug-in generates files that need to be stored centrally, but which aren't present in its installed source code.

How To Retrieve Files
---------------------
The storage location is private to the `CentralFileStorage` class and is not supposed to be accessed directly. Instead, you can ask the central file storage for the path to a particular file or directory that was previously stored. To do that, you would call the `CentralFileStorage.retrieve(...)` function.

The function takes the following arguments:
* The name/identifier of the stored item.
* The SHA256 hash of the file or directory you expect to match with the contents of the file or directory.
* The version number of the item to retrieve. If not provided, this defaults to version 1.0.0.

If the hash matches with the contents, the central file storage will give you a path to where the original file was moved. Otherwise it raises an error that someone might have edited the file without your knowing.

Security
--------
The central file storage is in a location where the user doesn't need administrator access to edit files. It is then possible to edit the files as they are stored in the central file storage. If the plug-in then does something with the contents of those files (e.g. decompressing a zip archive, executing DLLs, etc.) this would be an attack vector for a virus or a hacker.

This is where the hashes come in. The files not stored centrally can only be retrieved by providing the hash of the file. The file is checked against that hash before the path to the files is given. That would give an error if the file or directory was modified in any way. As long as the plug-in only accesses the files through the directories provided by the `retrieve` function, the hash will always be checked before accessing the files. As long as the source code of the plug-in cannot be edited (which is ensured by the signing of plug-ins itself) the process is considered secure.

This means though that looking for the central storage directory yourself is not secure. It needs to check the hash of the file, through the `retrieve` function, before accessing the files.