Jupiter - Cloud storage API - Specification
Jupiter should be implemented as REST API Server, with functional requirements being:
POST
/PUT
Uploading file to cloud storagePOST
/PUT
Updating file to cloud storage, perserving the link from old fileGET
Downloading fileGET
Receiving all data for logged user or avaliable folderGET
Getting info about filePOST
Creating database specified by Minerva APIPOST
Deleting selected filePOST
Creating user space, afterwards avaliable for user to upload files toPOST
Making file or directory publicPOST
Sharing file or directory with another user with given privilegesPOST
Increasing/Decreasing avaliable storage space for upgraded users
Except for given request, this service should realize the following features:
- Controlling the internal structure of file-system, something like unix-like(Linux e.g.) systems directories. Basically meaning each user can have his own directory, and can access only that directory, while he can also see shared directories of other users. This means that engineers working on this service needs to implement some type of user privileges, possibly just by using authentication header.
- Internally, this service should be able to host any type of file, but should check the size of those files and should terminate upload or expansion of those files that exceed the total maximum size that is avaliable for user.
Before we start...
First thing we need to do here is to create simple functions for controlling the storage.
Each user will have UUID(will be generated by gateway, you should store it in your own database) that will be the name of his folder, too, the url-s of files uploaded by that user would be as follows:
jupiter.lws/get?file=UUID/name_of_file
or if it's inside some folder jupiter.lws/get?file=UUID/folder_name/name_of_file
All requests will contain username inside header, it will be sent by gateway and that is the only service which will this service communicate directly.
If the header does not contain username inside of a header, it means the user is not loged in, and he can access file only if its public.
If the header does contain a username, but it is not owner of a file or folder, then he can access it if he has the rights to access or is public.
Public files are public for view only, no one else can modify them. On the other hand, a user can give privileges to another user for modify or view. If the user can modify them, he can upload files to that folder, and it will go to that folder, not occuping space for user that uploaded it, but instead for the user who is owner of the file. The privileges for given directory is inherited by all files inside directory, meaning if the directory is public, then all files inside are public too.
Note that not everyone can execute this requests, if someone does not have privileges for given file or something similar, he should receive error instead.
1. Uploading file to cloud storage
URL: jupiter.lws/upload
or jupiter.lws/upload?dir=UUID/directory_name
In this request, a user should be able to upload a file, a message should contain a file in the body. The 2 links given as example are as follows:
jupiter.lws/upload
- Uploads to root directory of user, meaning the url generated for download would bejupiter.lws/get?file=UUID/file_name
\jupiter.lws/upload?dir=UUID/directory_name
- Uploads to sub-directory of users cloud storage, meaning the url generated for download would bejupiter.lws/upload?dir=UUID/directory_name/file_name
Response should be simple:
{ "status": "STATUS FIELD CAN BE SUCCESS OR FALSE", "message" : "DESCRIBE THE SCENARIO THAT HAPPENED OR URL TO THE FILE",}
2. Updating file to cloud storage
URL: jupiter.lws/update?file=url_to_file
In this request, a user should be able to upload a file, a message should contain a file in the body. Response should be simple:
{ "status": "STATUS FIELD CAN BE SUCCESS OR FALSE", "message" : "DESCRIBE THE SCENARIO THAT HAPPENED",}
No need to respond with url, it is same
3. Downloading file
URL: jupiter.lws/get?file=url_to_file
In this request, a user should simply call GET request to receive the file downloaded, the response should be the file itself.
Here you will have to make sure that user that has no privilege to see this file gets rejected with error response. Basically, the reponse is either a file or Not authorized
.
4. Receiving all data for logged user or avaliable folder
URL: jupiter.lws/get
or jupiter.lws/get?full=false
or jupiter.lws/get?dir=name_of_directory&full=false
In this request, a user requests to get view of his directory, It has few possible scenarios, given in header
jupiter.lws/get
- This is the most basic scenario, in this scenario a user should receive json with all files, this returns full scope of everything inside the root directory, like this:
{ "path": "/", "max_storage": "1GB", "occupied": "324MB", "files" : [ { "name": "example_file_1", "size": "20MB", "dir" : false }, { "name": "example_dir_1", "size": "300MB", "dir" : true, "files" : [ { "name": "example_file_2", "size": "50MB", "dir" : false }, { "name": "example_file_3", "size": "50MB", "dir" : false }, { "name": "example_dir_2", "size": "200MB", "dir" : true, "files" : [ { "name": "example_file_4", "size": "100MB", "dir" : false }, { "name": "example_file_5", "size": "100MB", "dir" : false }, ] } ] } ]}
jupiter.lws/get?full=false
-full
flag can be left of or set to true to show everything inside the root directory, but can be set to true, then it will show just information about first files/directories shown, it will not go in depth. As for example above:
{ "path": "/", "max_storage": "1GB", "occupied": "324MB", "files" : [ { "name": "example_file_1", "size": "20MB", "dir" : false }, { "name": "example_dir_1", "size": "300MB", "dir" : true } ]}
jupiter.lws/get?dir=name_of_directory&full=false
- User can also specify which directory he wants to look at, he can still specify if he wants it full or not, if not, and he wants to see everything insideexample_dir_2
directory, he would send get request like this :jupiter.lws/get?dir=example_dir_1%2Fexample_dir_2&full=false
,%2F
is escape code for/
, but in url you can't send/
, it is ambiguous. The response for it would be:
{ "name": "/example_dir_1/example_dir_2", "size": "200MB", "files" : [ { "name": "example_file_4", "size": "100MB", "dir" : false }, { "name": "example_file_5", "size": "100MB", "dir" : false }, ]}
If full was set to true, it would show everything in subdirectories, too. But there are none inside this directory.
5. Getting info about file
URL: jupiter.lws/info?path=url_to_file
or jupiter.lws/info?path=url_to_directory
This request should return everything about the certain file or directory, the response should look like this:
{ "real_path": "path on hard disk, for example /home/lws/jupiter/storage/UUID/nice_image.png", "size": "2MB", "public": true, //(or false) "shared" : [ { "username": "marko", "privilege": "view" //or modify? }, { "username": "mateja", "privilege": "modify" //or view? }, { "username": "marija", "privilege": "view" //or modify? } ]}
6. Creating database specified by Minerva API
URL: jupiter.lws/db?name=database_name
This request will be sent by Minerva, trough Mercury. This is actually pretty simple, all you need to do is touch(create empty) file and return the path of file on machine. Response would be:
{ "path" : "/home/lws/jupiter/storage/UUID/database1.db"}
7. Deleting selected file
URL: jupiter.lws/delete?path=path_to_file_or_dir
This request will delete a file or directory from cloud storage. The response would look like:
{ "status": "success", // or not? "message": "200MB", // or why it failed "free": "834MB", "used": "166MB"}
If this request returns success, in message, return the size of freed space, if it fails, in message, returns why it fails.
8. Creating user space, afterwards avaliable for user to upload files to
URL: jupiter.lws/create
This request will be sent by Mercury upon registering. The request would look like this:
{ "username": "some_username", "uuid": "user_unique_id"}
It should create default free space, and return response with status with appropriate message.
9. Making file or directory public
URL: jupiter.lws/mkpublic?path=path_to_dir_or_file
This request should make directory or certain file public and return response with status and appropriate message.
10. Sharing file or directory with another user with given privileges
URL: jupiter.lws/share
The body of this request should look like this:
{ "path": "path_to_dir_or_file", "username": "username_that_gets_shared", "privilege": "view" // or modify?}
The request should make it shared with given user and return response:
{ "status": "status", "message": "if successful, return path, if false, return message"}
11. Increasing/Decreasing avaliable storage space for upgraded users
URL: jupiter.lws/storage?size=some_size
This request should increase or decrease the maximum storage avaliable and make it specified by value of size
. In case the storage decreases by some size that is smaller then current occupied space, you should just ignore the further uploads until user deletes the files to free up space.
The response should be:
{ "status": "success", //or not "message": "describe it", "free": "20GB", "max_storage": "24GB"}
- 1. Uploading file to cloud storage
- 2. Updating file to cloud storage
- 3. Downloading file
- 4. Receiving all data for logged user or avaliable folder
- 5. Getting info about file
- 6. Creating database specified by Minerva API
- 7. Deleting selected file
- 8. Creating user space, afterwards avaliable for user to upload files to
- 9. Making file or directory public
- 10. Sharing file or directory with another user with given privileges
- 11. Increasing/Decreasing avaliable storage space for upgraded users