feathersjs-ecosystem / feathers-blob

Feathers service for blob storage, like S3.
http://feathersjs.com
MIT License
92 stars 32 forks source link

Add S3 Params when uploading files. #8

Closed silvestreh closed 8 years ago

silvestreh commented 8 years ago

When setting S3 params you can, for example, set the permissions for an uploaded file. This uses the query object that is inside the request's params.

Fixes #7

silvestreh commented 8 years ago

Client-side it would look like

uploadsService.create({ uri: this.image }, { query: { ACL: 'public-read' } });
daffl commented 8 years ago

I'm not entirely sure how the S3 upload works but wouldn't any user now be able to set the permissions on an S3 bucket?

silvestreh commented 8 years ago

My service has an auth hook to ensure the request comes from an authenticated user. Here's what it looks like:

// my-app/src/services/upload/index.js
'use strict';

const hooks = require('./hooks');
const AWS = require('aws-sdk');
const Store = require('s3-blob-store');

// this is `require`ing the forked feathers-blob which is, as you can appreciate, 
// in a completely different path than my app
const BlobService = require('../../../../../../feathers-blob/lib');

module.exports = function () {
    const app = this;
    const s3 = new AWS.S3(app.get('amazon'));
    const blobStore = Store({
        client: s3,
        bucket: 'tfm-site-help'
    });

    const blobService = BlobService({
        Model: blobStore
    });

    // Initialize our service with any options it requires
    app.use('/uploads', blobService);

    // Get our initialize service to that we can bind hooks
    const uploadService = app.service('/uploads');

    // Set up our hooks
    uploadService.before(hooks.before);
    uploadService.after(hooks.after);
};

So, if I understand Feathers correctly, a user can only change the permissions for the file he is currently uploading. Not other existing files and probably not the bucket itself (I have limited experience with AWS, but I've been told the ALC permissions work on a file-basis and don't mess with the entire bucket.)

silvestreh commented 8 years ago

I changed it so it will look for a params.s3 object in the request. This object can be set inside a before hook in a service like the one above.

daffl commented 8 years ago

Perfect, this looks good. As discussed on Slack we can now set the permissions in a hook like this:

app.service('upload').before({
  create(hook) {
    hook.params.s3 = { ACL: 'public-read' };
  }
});
daffl commented 8 years ago

Released in v1.2.0. Thank you for the PR!