Skip to content

Instantly share code, notes, and snippets.

@donpark
Created September 19, 2016 09:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save donpark/a541684f6b81a35f2453f543b5f961ac to your computer and use it in GitHub Desktop.
Save donpark/a541684f6b81a35f2453f543b5f961ac to your computer and use it in GitHub Desktop.
const Async = require('async')
const AWS = require('aws-sdk')
const UUID = require('node-uuid')
const config = require('./config')
class S3 {
constructor(options = {}) {
if (!options.accessKey) throw new Error('required S3 accessKey missing');
if (!options.secretKey) throw new Error('required S3 secretKey missing');
if (!options.region) throw new Error('required S3 region missing');
let s3opts = {
signatureVersion: 'v4',
accessKeyId: options.accessKey,
secretAccessKey: options.secretKey,
region: options.region,
}
if (options.endpoint) {
const endpoint = URL.parse(options.endpoint)
s3opts = Object.assign(s3opts, {
endpoint: options.endpoint,
s3ForcePathStyle: true,
s3BucketEndpoint: false,
sslEnabled: endpoint.protocol === 'https:',
})
this.isMinio = true
} else {
this.isMinio = false
}
if (TRACE) console.log('S3 options', s3opts);
this.client = new AWS.S3(s3opts)
}
...
ensureBucketPublicAccess(bucket) {
if (TRACE) console.log('ensureBucketPublicAccess', bucket);
// Promise complicates retry so uses callback here.
return new Promise((resolve, reject) => {
this.client.getBucketPolicy({
Bucket: bucket,
}, (err, data) => {
let policy = !err && data && data.Policy ? JSON.parse(data.Policy) : null
if (policy && this.isPublicAccessPolicy(policy)) return resolve(policy);
// policy either doesn't exist or is not set to public access, create or override
policy = {
"Id": UUID.v4(),
"Version": "2012-10-17",
"Statement": [
{
"Sid": UUID.v4(),
"Action": [
"s3:GetObject",
],
"Effect": "Allow",
"Resource": [
`arn:aws:s3:::${bucket}/*`
],
"Principal": {
"AWS": [ "*" ]
}
}
]
}
this.client.putBucketPolicy({
Bucket: bucket,
Policy: JSON.stringify(policy),
}, (err, data) => {
if (err) return reject(err);
// make sure correct policy is set
this.client.getBucketPolicy({
Bucket: bucket,
}, (err, data) => {
if (err) return reject(err);
policy = data && data.Policy ? JSON.parse(data.Policy) : null
if (policy && this.isPublicAccessPolicy(policy)) return resolve(policy);
reject(new Error('could not set public access policy'))
})
})
})
})
}
headObject(bucket, objectName) {
if (TRACE) console.log('headObject', objectName);
return this.client.headObject({
Bucket: bucket,
Key: objectName,
}).promise()
}
getObject(bucket, objectName, head = false) {
if (TRACE) console.log('getObject', objectName);
if (head) {
return this.headObject(bucket, objectName)
.then(data => {
const request = this.client.getObject({
Bucket: bucket,
Key: objectName,
})
return Promise.resolve(request.createReadStream())
})
}
const request = this.client.getObject({
Bucket: bucket,
Key: objectName,
})
return Promise.resolve(request.createReadStream())
}
putObject(bucket, objectName, stream, size, mimeType, acl = 'public-read') {
if (TRACE) console.log('putObject', objectName);
return this.client.putObject({
Bucket: bucket,
Key: objectName,
Body: stream,
ContentLength: size,
ContentType: mimeType,
})
.promise()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment