Home

Awesome

File uploader

Build
Status

Description

mojfile-uploader is designed as a drop-in component that can be added to any project to facilitate users uploading files.

Any files that are uploaded are passed through ClamAV virus scanning, which runs on a pair of bundled docker containers (one running the ClamAV daemon, and the other exposing a REST interface to it).

Clean files are uploaded to an Azure Blob Storage container. Infected files are rejected.

The assumption here is that files are being uploaded by users, but that a separate admin interface will be used to download the files. This means that, if the user's credentials/session are compromised, an attacker would not be able to view the content of any of the user's uploaded files. To this end;

The uploader can list the uploaded files, and can delete any of them (so that the user can correct mistakes).

At the root level of the container, the uploader creates collections, which are a group of related files. You can add files to a collection explicitly by specifying its name, or implicitly have it create a new collection by leaving out the name. Underneath collections, the uploader optionally supports a single level of (sub)folders.

API documentation

A client gem has been published that simplifies the interaction with the uploader API from Ruby apps.

Adding files

Request. If no collection_ref route parameter is provided, a new collection will be created.

POST to '/?:collection_ref?/new'
with a JSON payload
{folder: 'subfolder', file_filename: 'filename', file_data: 'Base64 encoded file data'}

Response:

When success:
    200 status code
    JSON body: { collection: 'collection reference', folder: 'subfolder', key: 'filename' }

When virus detected:
    400 status code
    JSON body: { errors: ['Virus scan failed'] }

When failure:
    422 status code
    JSON body: { errors: ['file_filename must be provided', 'file_data must be provided'] }

Deleting files

Request:

DELETE to '/:collection_ref/?:folder?/:filename'

Response:

204 status code

Listing files

Request:

GET to '/:collection_ref/?:folder?'

Response:

When success:
    200 status code
    JSON body: { collection: '12345', folder: 'subfolder', files: [{ key: '12345/subfolder/test.doc', title: 'test.doc', last_modified: '2016-12-05T12:20:02.000Z' }] }

When collection not found:
    404 status code
    JSON body: { errors: ["Collection '12345' does not exist or is empty."] }

Setup

An Azure Blob Storage container is required to store the uploaded files. This container should have the minimum possible permissions; list blobs, put blob, delete blob.

Note on Azure Storage Credentials

The azure-storage-blob gem will use the following ENV vars by default:

Run Locally

Create the .env file

cp .env.example .env

Update the details in that file.

You can create a new Azure storage in the Azure Portal stgttfilestore account

Then in any account you want to use to access MOJFile-Uploader using MOJFile-Uploader-API-Client, please update: AZURE_STORAGE_ACCOUNT AZURE_STORAGE_ACCESS_KEY CONTAINER_NAME

With docker - no longer supported

docker-compose build
docker-compose up

The above commands will create and run the uploader and the AV scanner containers.

Without docker

Run:

DO_NOT_SCAN=true dotenv rackup

If you do not want to skip virus scanning, The AV scanner must be running before you start the uploader. Then run:

dotenv rackup

Scanner endpoint

If the virus scanner is not available from this application at http://clamav-rest:8080/scan then you will need to set the SCANNER_URL environment variable to point at the correct endpoint. It should be available if the app is launched using docker compose.

Testing

The File uploader is tested using RSpec, mutation testing and rubocop. To test, run:

bundle install
bundle exec rake

File uploader example app

Included in the directory example_app there is a simple Sinatra app to show how to integrate the File Uploader JQuery plugin with the client gem.

Running the app

First make sure in file example_app/config.ru the HttpClient base_url points to the right URL/port where the MOJ Uploader app is running.

In the example_app directory, run:

bundle
bundle exec puma -p 3003  # or any other port you want

Go to http://localhost:3003 to see the uploader example.