Skip to content

Commit

Permalink
Merge pull request #101 from CulturalMe/devel
Browse files Browse the repository at this point in the history
Version  0.7.0
  • Loading branch information
gsuess committed May 18, 2015
2 parents 3e2b96a + d9e7e72 commit 1e654e8
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 14 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
Slingshot Changelog
===================

## Version 0.7.0

### Enhancements

* Added `Slingshot.S3Storage.TempCredentials`. Thanks @jossoco

### Bug Fixes

* Fixed character encoding for content-disposition for AWS-S3 based directives ([#95](https://github.com/CulturalMe/meteor-slingshot/issues/95)). Thanks @timtch.

## Version 0.6.2

Removed debugging log.
Expand Down
76 changes: 67 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,53 @@ Slingshot.createDirective("aws-s3-example", Slingshot.S3Storage, {
});
```

#### S3 with temporary AWS Credentials (Advanced)

For extra security you can use
[temporary credentials](http://docs.aws.amazon.com/STS/latest/UsingSTS/CreatingSessionTokens.html) to sign upload requests.

```JavaScript
var sts = new AWS.STS(); // Using the AWS SDK to retrieve temporary credentials

Slingshot.createDirective('myUploads', Slingshot.S3Storage.TempCredentials, {
bucket: 'myBucket',
temporaryCredentials: Meteor.wrapAsync(function (expire, callback) {
//AWS dictates that the minimum duration must be 900 seconds:
var duration = Math.max(Math.round(expire / 1000), 900);

sts.getSessionToken({
DurationSeconds: duration
}, function (error, result) {
callback(error, result && result.Credentials);
});
})
});
```

If you are running slingshot on an EC2 instance, you can conveniantly retreive
your access keys with [`AWS.EC2MetadataCredentials`](http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/EC2MetadataCredentials.html):

```JavaScript
var credentials = new AWS.EC2MetadataCredentials();

var updateCredentials = Meteor.wrapAsync(credentials.get, credentials);

Slingshot.createDirective('myUploads', Slingshot.S3Storage.TempCredentials, {
bucket: 'myBucket',
temporaryCredentials: function () {
if (credentials.needsRefresh()) {
updateCredentials();
}

return {
AccessKeyId: credentials.accessKeyId,
SecretAccessKey: credentials.secretAccessKey,
SessionToken: credentials.sessionToken
};
}
});
```

### Google Cloud

[Generate a private key](http://goo.gl/kxt5qz) and convert it to a `.pem` file
Expand Down Expand Up @@ -457,10 +504,7 @@ i.e. `"https://d111111abcdef8.cloudfront.net"`
`expire` Number (optional) - Number of milliseconds in which an upload
authorization will expire after the request was made. Default is 5 minutes.

#### AWS S3

`bucket` String (**required**) - Name of bucket to use. The default is
`Meteor.settings.S3Bucket`.
#### AWS S3 (`Slingshot.S3Storage`)

`region` String (optional) - Default is `Meteor.settings.AWSRegion` or
"us-east-1". [See AWS Regions](http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region)
Expand All @@ -469,7 +513,17 @@ authorization will expire after the request was made. Default is 5 minutes.

`AWSSecretAccessKey` String (**required**) - Can also be set in `Meteor.settings`.

#### Google Cloud Storage
#### AWS S3 with Temporary Credentials (`Slingshot.S3Storage.TempCredentials`)

`region` String (optional) - Default is `Meteor.settings.AWSRegion` or
"us-east-1". [See AWS Regions](http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region)

`temporaryCredentials` Function (**required**) - Function that generates temporary
credentials. It takes a signle argument, which is the minumum desired expiration
time in milli-seconds and it returns an object that contains `AccessKeyId`,
`SecretAccessKey` and `SessionToken`.

#### Google Cloud Storage (`Slingshot.GoogleCloud`)

`bucket` String (**required**) - Name of bucket to use. The default is
`Meteor.settings.GoogleCloudBucket`.
Expand Down Expand Up @@ -500,19 +554,23 @@ the second is the meta-information that can be passed by the client.
`contentDisposition` String (optional) - RFC 2616 Content-Disposition directive.
Default is the uploaded file's name (inline). Use null to disable.

#### Rackspace Cloud
#### Rackspace Cloud (`Slingshot.RackspaceFiles`)

`RackspaceAccountId` String (**required**) - Can also be set in `Meteor.settings`.

`RackspaceMetaDataKey` String (**required**) - Can also be set in `Meteor.settings`.

`container` String (**required**) - Name of container to use.

`region` String (optional) - Data Center region. The default is `"iad3"`. [See other regions](http://docs.rackspace.com/files/api/v1/cf-devguide/content/Service-Access-Endpoints-d1e003.html)
`region` String (optional) - Data Center region. The default is `"iad3"`.
[See other regions](http://docs.rackspace.com/files/api/v1/cf-devguide/content/Service-Access-Endpoints-d1e003.html)

`pathPrefix` String or Function (**required**) - Simlar to `key` for S3, but will always be appended by `file.name` that is provided by the client.
`pathPrefix` String or Function (**required**) - Similar to `key` for S3, but
will always be appended by `file.name` that is provided by the client.

`deleteAt` Date (optional) - Absolute time when the uploaded file is to be deleted. _This attribute is not enforced at all. It can be easily altered by the client_
`deleteAt` Date (optional) - Absolute time when the uploaded file is to be
deleted. _This attribute is not enforced at all. It can be easily altered by the
client_

`deleteAfter` Number (optional) - Same as `deleteAt`, but relative.

Expand Down
2 changes: 1 addition & 1 deletion package.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package.describe({
name: "edgee:slingshot",
summary: "Directly post files to cloud storage services, such as AWS-S3.",
version: "0.6.2",
version: "0.7.0",
git: "https://github.com/CulturalMe/meteor-slingshot"
});

Expand Down
38 changes: 34 additions & 4 deletions services/aws-s3.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,7 @@ Slingshot.S3Storage = {
*/

upload: function (method, directive, file, meta) {
var url = Npm.require("url"),

policy = new Slingshot.StoragePolicy()
var policy = new Slingshot.StoragePolicy()
.expireIn(directive.expire)
.contentLength(0, Math.min(file.size, directive.maxSize || Infinity)),

Expand All @@ -89,7 +87,8 @@ Slingshot.S3Storage = {

"Cache-Control": directive.cacheControl,
"Content-Disposition": directive.contentDisposition || file.name &&
"inline; filename=" + quoteString(file.name, '"')
"inline; filename=" + quoteString(file.name, '"') +
"; filename*=utf-8''" + encodeURIComponent(file.name)
},

bucketUrl = _.isFunction(directive.bucketUrl) ?
Expand Down Expand Up @@ -170,6 +169,37 @@ Slingshot.S3Storage = {
}
};

Slingshot.S3Storage.TempCredentials = _.defaults({

directiveMatch: _.chain(Slingshot.S3Storage.directiveMatch)
.omit("AWSAccessKeyId", "AWSSecretAccessKey")
.extend({
temporaryCredentials: Function
})
.value(),

directiveDefault: _.omit(Slingshot.S3Storage.directiveDefault,
"AWSAccessKeyId", "AWSSecretAccessKey"),

applySignature: function (payload, policy, directive) {
var credentials = directive.temporaryCredentials(directive.expire);

check(credentials, Match.ObjectIncluding({
AccessKeyId: Slingshot.S3Storage.directiveMatch.AWSAccessKeyId,
SecretAccessKey: Slingshot.S3Storage.directiveMatch.AWSSecretAccessKey,
SessionToken: String
}));

payload["x-amz-security-token"] = credentials.SessionToken;

return Slingshot.S3Storage.applySignature
.call(this, payload, policy, _.defaults({
AWSAccessKeyId: credentials.AccessKeyId,
AWSSecretAccessKey: credentials.SecretAccessKey
}, directive));
}
}, Slingshot.S3Storage);

function quoteString(string, quotes) {
return quotes + string.replace(quotes, '\\' + quotes) + quotes;
}
Expand Down

0 comments on commit 1e654e8

Please sign in to comment.