-
-
Notifications
You must be signed in to change notification settings - Fork 494
File Management System
File Management System is an extension of functionality for Bassa, where the users can now keep their files and folders in an organised fashion on the server, as well as share resources among other users. The idea is to take a leap toward a cloud-based storage service for resources, similar to existing drive services. The file system is based on an Access Control List(ACL) model, which allows for three levels of permission to users while sharing resources with others namely OWNER
, WRITE
and READ
. On the basis of these operations, the users can perform the following actions on shared resources:
- OWNER: Create, Read, Update, Delete
- WRITE: Create, Read, Update
- READ: Read
The service has the following functionalities:
- Neat classification into folders and files
- CRUD and move operations on folders and files
- Uploading files to the server
- Sharing folders and files with multiple users
- Granting varying permission to users with whom the resources are shared (OWNER, WRITE, READ)
- CRUD operations on shared resources depending on permission
- Broadcasting notifications for every user when a download is completed, resource access is granted or signup requests are approved
Following tables are used to manage data:
-
ACL: This table stores information about the resources that are shared by the user among other users. Every row contains a user_id column which points to the user who has been granted access and has a foreign key constraint which references the user table. The id and entity column contain the id and the type of the resource (folder/file) and access column denotes the level of permission. (OWNER, READ, WRITE)
-
FOLDER: This table stores all the folders in the system for every user. The id and name columns are used for the majority of the CRUD operations while the parent_id is used to maintain a hierarchy on the frontend. This contains a reference to the parent resource, which is always a folder in the same table. The user_id stores the reference to the user to whom the folder belongs. Note that this table only contains resources which are created by users themselves, and not been granted access to.
-
FILE: This table is similar to the folder table, with an extra path column which stores the path of the file on the server when it is uploaded inside a folder. The reference to the parent folder is stored in parent_id and is a foreign key referencing the id in folder table.
-
NOTIFICATIONS: This table stores all the notifications generated for all the users, and has a foreign key reference to the id in the user table.
The backend contains an abstract class acting as a model for a resource. This design realisation comes from the fact that both folders and files largely have similar CRUD operations to perform over, with the exception of fetching children and uploading which are exclusive to folders and files respectively. The respective File and Folder models are simply classes of the resource base class. This firstly helps in maintaining a central blueprint for resources in case more entities are required in the future of similar kind. Secondly, this helps in reducing code volume since the endpoints have to only operate upon a single resource class, which can decide which entity to delegate the code to, depending upon, say, a query parameter which specifies whether a file or a folder is to be modified. Separate entities require separate routes and logic to handle which can often be redundant or tiresome to maintain.
The APIs consist of resource, notification, permission and uploading endpoints. Please refer to the URL Endpoint Wiki for more extensive information on each of them.
- The resource endpoints handle CRUD and move folder/file operations, depending on the type of resource.
- The permission endpoints handle permission checks and grants for particular resources to certain user ids.
- The notification endpoints handle fetch and save of generated notifications for every user.
- The upload endpoint handles the incoming multipart form data and uploads it to the server.
The frontend is built on AngularJS with future plans of migration to newer technologies like React. The structure consists of public logic and component-specific logic. Components are all the small parts and functionalities of the app that are bootstrapped together. Every component consists of controllers (responsible for binding the scope between models and views in the MVC structure), services (injectable blocks of code containing or fetching data, can be regarded as data models) and views (HTML templates for the component).
Although there are a bunch of components that are built for implementing the file system, following controllers and services are pivotal to the core functionality:
- ACL Service
- Drive Controller
- Notification Service
- Upload Controller
The ACL Service is a global service which handles the entire flow of navigating into and out of a folder. It maintains the context of the current folder and its permission level for a user. It is basically a stack with each element being a pair of the current folder id and its permission access for that particular user. The permission defaults to OWNER
while viewing their own folders/files and changes accordingly while viewing the shared documents. The stack contents signify the nested level in the directory tree, with each push meaning entering a folder and each pop meaning navigating back to the previous state. This design is required for storing permissions for every level in the tree. This service is injected in the Drive Controller.
The Drive Controller handles all the CRUD operations on resources depending on the permissions. It initialises by fetching children of a root folder element and all the resources shared by the user. The shared and owned flows both have the same template and logic. For CRUD operations, permissions are checked for every entity. This method defaults to OWNER
in case the user in his own directory tree. The method checks the existing top of the context stack for permission to the current folder (in which the user is) and compares it to the permission of the resource in question (which has to be shared). The priority is given to the explicit permission of the entity to incorporate cases where the user has special/restricted permission to that resource (irrespective of the permission level of the parent folder). Based on the resulting access level, the user can CRUD on the entity. The back navigation is explicitly handled to maintain the ACL stack by popping current context and fetching children for the new parent_id on top of the stack.
The Notification service handles fetching and saving notifications in the following cases:
- When a queued user download completes
- When a user signup request is approved
- When a user is granted access to a resource
The fetch method is a poller function which polls for notifications for that user after a set interval of time and also when the user wishes to read the notifications. Based on whether there are any new notifications, the frontend handles the view of the display icon. The save event is fired during the aforementioned three scenarios. The notification service is injectable into other controllers.
The Upload service is responsible for wrapping the incoming file type into form data object and send it as a multipart form-data to the backend internally which uploads the file to the server. The User service handles user session, id and username for various methods which require them.
The aforementioned flow allows the user to seamlessly navigate through their directory tree and upload files and add folders. It also allows users to comfortably share resources with each other along with permission restrictions.
Some foreseeable future scopes for this project are upload tweaks like upload limits and automatic ZIP file conversions for large files and a user group construct for better managing the resource sharing.