star 0.0.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/.rspec +2 -0
- data/.travis.yml +4 -1
- data/CHANGELOG.md +11 -0
- data/{LICENSE.txt → MIT-LICENSE} +1 -1
- data/README.md +199 -19
- data/Rakefile +6 -0
- data/bin/console +4 -4
- data/lib/star.rb +2 -2
- data/lib/star/config.rb +50 -0
- data/lib/star/configuration.rb +63 -0
- data/lib/star/file.rb +111 -0
- data/lib/star/version.rb +1 -1
- data/star.gemspec +9 -5
- metadata +57 -7
- data/CODE_OF_CONDUCT.md +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d65b0fde4ed074e01ff2192432f6af5e6058be1b
|
4
|
+
data.tar.gz: 488bad2de6d544176508a8ffe88d2821ac96b8df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3efd5c969edb847e4d07a6be67e6cb50b96957f8b1d1b9433545fa8ff30d4afe0f5bac345b683b05301c0b351c914aedece904be91869b65c27762c64026bd3c
|
7
|
+
data.tar.gz: 96edc054dd043f85e3c32d8285cc173cef2a6b7e6aaf4007dce5fa07e7cb90157ce3efb6b1a7fa3b8447fa4702192821160c9d61bce2dd9695eb1341f7669916
|
data/.gitignore
CHANGED
data/.rspec
ADDED
data/.travis.yml
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
|
3
|
+
- 2.2.3
|
4
4
|
before_install: gem install bundler -v 1.10.6
|
5
|
+
env:
|
6
|
+
matrix:
|
7
|
+
- secure: ZqWedYLyWoAdrXIOfQfP7XXk1iwhM4BOql1tufimM/K8KELAhQHILKLiCodnBeFptUoBQgkIaGKLRxSD+g7epzeCzLZoUV1H9DbGf0wR6dJI0ZJKFJMMKu2GVl13+CLkO2zvGciEXmvL1Vj/kvHtyBRddeeCVZgq5f65YU5rpS+pzl5v1rWia24ikK+uUKxvYxyN+owIN+GpvHAFrJ5vMpppmrlSU5OGO1S2KtaX09OxgTxM7Jo0s1Zls0eAtZMdKqdg8hW8u3I8M4Jyu7DRYdalwgZX5BEnjIpr2xBMwHOskVfuUMOnaH5FMCxUSDKHW5j7priRFayN0m+MlBRvb8u3Z3ZIVQx0Jboy1JbnDlqZCHhqGQvCfUJpJiLVi/V7qqXIUjOzB/abI1bQ3pFROF3SNEK0lEGZgzCiilrRBs5RNA/aOokcKof5DGzY68pbXZ0hAWYJmZzU5zrvmGWna77JRnPS3ueXQF5cq5xUYtOhY36HB5gyKReld9/UORZSPmtInADvtBcFjF7AQzGoReRnJNlhQbPTufJpA9iBVc5vm3h6ZeLhThKhLmZIzm0RcWwf8AHXYhnjZansVdMocjtZd5RLKHJANIEKJe28hZqnJa/uamlKjZqqgc/4hYky7XI38fMY3Bbh2lmWPgikjL75QvhXTVk+z5r4QYNwNsQ=
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
For more information about changelogs, check
|
6
|
+
[Keep a Changelog](http://keepachangelog.com) and
|
7
|
+
[Vandamme](http://tech-angels.github.io/vandamme).
|
8
|
+
|
9
|
+
## 1.0.0 - 2015.10.26
|
10
|
+
|
11
|
+
* [FEATURE] Add `Star::File` to write/read files on S3
|
data/{LICENSE.txt → MIT-LICENSE}
RENAMED
data/README.md
CHANGED
@@ -1,41 +1,221 @@
|
|
1
|
-
|
1
|
+
:star2: :star2: Store archives privately on S3 :star2: :star2:
|
2
|
+
==============================================================
|
2
3
|
|
3
|
-
|
4
|
+
Star helps you write Ruby apps that need to store files on S3 and retrieve them with expiring URLs.
|
4
5
|
|
5
|
-
|
6
|
+
The **source code** is available on [GitHub](https://github.com/Fullscreen/star) and the **documentation** on [RubyDoc](http://www.rubydoc.info/github/Fullscreen/star/master/Star/Interface).
|
6
7
|
|
7
|
-
|
8
|
+
[![Build Status](http://img.shields.io/travis/Fullscreen/star/master.svg)](https://travis-ci.org/Fullscreen/star)
|
9
|
+
[![Coverage Status](http://img.shields.io/coveralls/Fullscreen/star/master.svg)](https://coveralls.io/r/Fullscreen/star)
|
10
|
+
[![Dependency Status](http://img.shields.io/gemnasium/Fullscreen/star.svg)](https://gemnasium.com/Fullscreen/star)
|
11
|
+
[![Code Climate](http://img.shields.io/codeclimate/github/Fullscreen/star.svg)](https://codeclimate.com/github/Fullscreen/star)
|
12
|
+
[![Online docs](http://img.shields.io/badge/docs-✓-green.svg)](http://www.rubydoc.info/github/Fullscreen/star/master/Star/File)
|
13
|
+
[![Gem Version](http://img.shields.io/gem/v/star.svg)](http://rubygems.org/gems/star)
|
8
14
|
|
9
|
-
|
15
|
+
|
16
|
+
After [configuring your app](#how-to-configure), you can write a file to S3 by running:
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
file = Star::File.new
|
20
|
+
file.open{|f| f << "some text to store in a remote file"}
|
21
|
+
```
|
22
|
+
|
23
|
+
You can successively retrieve the same file from S3 by calling:
|
10
24
|
|
11
25
|
```ruby
|
12
|
-
|
26
|
+
url = file.url
|
13
27
|
```
|
14
28
|
|
15
|
-
|
29
|
+
This will provide a URL that everyone can access *for the next 30 seconds*.
|
30
|
+
|
31
|
+
After 30 seconds, access to the file using that URL [will be denied](http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-signed-urls.html#private-content-overview-choosing-duration).
|
32
|
+
|
33
|
+
Why use Star
|
34
|
+
============
|
35
|
+
|
36
|
+
Star is not the only Ruby library to help developers store archives on S3.
|
37
|
+
However, most other libraries are [huge](https://rubygems.org/gems/aws-sdk-core) and [heavy on dependencies](https://github.com/fog/fog/blob/master/fog.gemspec#L50-L100).
|
38
|
+
|
39
|
+
Star does one thing, and does it well.
|
40
|
+
The codebase is small and there are no runtime dependencies.
|
41
|
+
This means less footprint on your app, and code that is easier to read, maintain and upgrade.
|
16
42
|
|
17
|
-
|
43
|
+
How to install
|
44
|
+
==============
|
18
45
|
|
19
|
-
|
46
|
+
To install on your system, run
|
20
47
|
|
21
|
-
|
48
|
+
gem install star
|
49
|
+
|
50
|
+
To use inside a bundled Ruby project, add this line to the Gemfile:
|
51
|
+
|
52
|
+
gem 'star', '~> 1.0'
|
53
|
+
|
54
|
+
|
55
|
+
How to use
|
56
|
+
==========
|
57
|
+
|
58
|
+
To write a file to S3, [configure your app](#how-to-configure), then create a new remote file
|
59
|
+
instance:
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
file = Star::File.new
|
63
|
+
```
|
22
64
|
|
23
|
-
|
65
|
+
You can now call any method you would normally use to add content to a
|
66
|
+
`File`, for instance:
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
file.open do |f|
|
70
|
+
f << "append some text"
|
71
|
+
f.write "write some other text"
|
72
|
+
f.writeln "write a line of text"
|
73
|
+
end
|
74
|
+
```
|
75
|
+
|
76
|
+
Once the file is closed, Star will automatically upload it to S3.
|
77
|
+
|
78
|
+
To read the same file from S3, get its URL by calling
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
file.url
|
82
|
+
```
|
83
|
+
|
84
|
+
By default, this URL will only be publicly available for 30 seconds.
|
85
|
+
This is useful to let your users download the file, while preventing them
|
86
|
+
from sharing the URL and having other (unauthenticated) users download it.
|
87
|
+
|
88
|
+
Options
|
89
|
+
-------
|
90
|
+
|
91
|
+
When you create a new remote file instance, you can set these options:
|
92
|
+
|
93
|
+
* `name`: the file name (defaults to `'attachment'`)
|
94
|
+
* `content_type`: the content type for the file (defaults to `'application/octet-stream'`)
|
95
|
+
* `folder`: the remote folder where to store the file (defaults to `'attachments'`)
|
96
|
+
|
97
|
+
For instance, you can call `File.new` with these options:
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
Star::File.new name: 'test.csv', content_type: 'text/csv', folder: 'spreadsheets'
|
101
|
+
```
|
24
102
|
|
25
|
-
|
103
|
+
How to configure
|
104
|
+
================
|
26
105
|
|
27
|
-
|
106
|
+
In order to use Star you must have an [S3 account](https://aws.amazon.com/s3).
|
28
107
|
|
29
|
-
|
108
|
+
Log into your account to retrieve your access key ID, secret access key and
|
109
|
+
bucket name, then add the following code to your app:
|
30
110
|
|
31
|
-
|
111
|
+
```ruby
|
112
|
+
Star.configure do |config|
|
113
|
+
config.access_key_id = '<YOUR S3 ACCESS KEY ID>'
|
114
|
+
config.secret_access_key = '<YOUR S3 SECRET ACCESS KEY>'
|
115
|
+
config.bucket = '<YOUR S3 BUCKET NAME>'
|
116
|
+
end
|
117
|
+
```
|
118
|
+
|
119
|
+
Make sure that this code is run *before* you use Star.
|
120
|
+
For instance, in a Rails app, you can store this code in `config/initializers/star.rb`.
|
121
|
+
|
122
|
+
Star also provide two options that you can set in your configuration:
|
123
|
+
|
124
|
+
* `duration` specifies how many seconds the expiring URLs should be valid for (default: `30`)
|
125
|
+
* `location` specifies the subfolder of your bucket where files should be stored (default: `'/'`)
|
126
|
+
* `remote` specifies that files will be stored remotely on S3 (default: `true`)
|
127
|
+
|
128
|
+
For instance, your configuration could look like this:
|
129
|
+
|
130
|
+
```ruby
|
131
|
+
Star.configure do |config|
|
132
|
+
config.access_key_id = '<YOUR S3 ACCESS KEY ID>'
|
133
|
+
config.secret_access_key = '<YOUR S3 SECRET ACCESS KEY>'
|
134
|
+
config.bucket = '<YOUR S3 BUCKET NAME>'
|
135
|
+
config.duration = 60
|
136
|
+
config.location = 'production/uploads'
|
137
|
+
end
|
138
|
+
```
|
139
|
+
|
140
|
+
Configuring with environment variables
|
141
|
+
--------------------------------------
|
142
|
+
|
143
|
+
As an alternative to the approach above, you can configure your app with
|
144
|
+
environment variables. For instance, setting the following variables:
|
145
|
+
|
146
|
+
```bash
|
147
|
+
export AWS_ACCESS_KEY_ID="<YOUR S3 ACCESS KEY ID>"
|
148
|
+
export AWS_SECRET_ACCESS_KEY="<YOUR S3 SECRET ACCESS KEY>"
|
149
|
+
export AWS_BUCKET="<YOUR S3 BUCKET NAME>"
|
150
|
+
export STAR_DURATION="60"
|
151
|
+
export STAR_LOCATION="production/uploads"
|
152
|
+
```
|
153
|
+
|
154
|
+
is equivalent to configuring your app with the initializer above.
|
155
|
+
|
156
|
+
How to store files locally
|
157
|
+
==========================
|
158
|
+
|
159
|
+
If you set `Star.configuration.remote` to `false`, then your files will be
|
160
|
+
stored locally, rather than remotely on S3.
|
161
|
+
|
162
|
+
This is very convenient if you use Star in a Rails application.
|
163
|
+
By adding the following lines to `config/environments/development.rb`:
|
164
|
+
|
165
|
+
```ruby
|
166
|
+
Star.configure do |config|
|
167
|
+
config.remote = false
|
168
|
+
config.location = Rails.public_path
|
169
|
+
end
|
170
|
+
```
|
171
|
+
|
172
|
+
all your files will be stored in your `public/` folder while developing.
|
173
|
+
In production, your files will still be stored on S3.
|
174
|
+
|
175
|
+
Your Rails controller/action that redirects to a file might look like this:
|
176
|
+
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
if Star.remote?
|
180
|
+
redirect_to file.url
|
181
|
+
else
|
182
|
+
send_file file.path, type: file.content_type
|
183
|
+
end
|
184
|
+
```
|
185
|
+
|
186
|
+
How to contribute
|
187
|
+
=================
|
188
|
+
|
189
|
+
If you find that a method is missing, fork the project, add the missing code,
|
190
|
+
write the appropriate tests, then submit a pull request, and it will gladly
|
191
|
+
be merged!
|
192
|
+
|
193
|
+
In order to test, you need to have access to a S3 account that will be used
|
194
|
+
to upload and download test files.
|
195
|
+
|
196
|
+
Set the following environment variables to match your S3 account, then run
|
197
|
+
`rspec` to run the tests:
|
198
|
+
|
199
|
+
```bash
|
200
|
+
export STAR_TEST_AWS_ACCESS_KEY_ID="<YOUR TEST S3 ACCESS KEY ID>"
|
201
|
+
export STAR_TEST_SECRET_ACCESS_KEY="<YOUR TEST S3 SECRET ACCESS KEY>"
|
202
|
+
export STAR_TEST_BUCKET="<YOUR TEST S3 BUCKET NAME>"
|
203
|
+
export STAR_TEST_LOCATION="<YOUR TEST S3 FOLDER>"
|
204
|
+
```
|
32
205
|
|
33
|
-
|
206
|
+
How to release new versions
|
207
|
+
===========================
|
34
208
|
|
35
|
-
|
209
|
+
If you are a manager of this project, remember to upgrade the [Star gem](http://rubygems.org/gems/star)
|
210
|
+
whenever a new feature is added or a bug gets fixed.
|
36
211
|
|
212
|
+
Make sure all the tests are passing on [Travis CI](https://travis-ci.org/Fullscreen/star),
|
213
|
+
document the changes in CHANGELOG.md and README.md, bump the version, then run
|
37
214
|
|
38
|
-
|
215
|
+
rake release
|
39
216
|
|
40
|
-
|
217
|
+
Remember that the star gem follows [Semantic Versioning](http://semver.org).
|
218
|
+
Any new release that fixes bugs and does not add features should bump the *patch* version (1.0.x).
|
219
|
+
Any new release that is fully backward-compatible should bump the *minor* version (1.x.0).
|
220
|
+
Any new version that breaks compatibility should bump the *major* version (2.0.0).
|
41
221
|
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "bundler/setup"
|
4
|
+
require "star"
|
5
5
|
|
6
6
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
7
|
# with your gem easier. You can also use a different console, if you like.
|
8
8
|
|
9
9
|
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
-
# require
|
10
|
+
# require "pry"
|
11
11
|
# Pry.start
|
12
12
|
|
13
|
-
require
|
13
|
+
require "irb"
|
14
14
|
IRB.start
|
data/lib/star.rb
CHANGED
data/lib/star/config.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'star/configuration'
|
2
|
+
|
3
|
+
module Star
|
4
|
+
# Provides methods to read and write global configuration settings.
|
5
|
+
#
|
6
|
+
# @example Set the API key for a server-only YouTube app:
|
7
|
+
# Star.configure do |config|
|
8
|
+
# config.access_key_id = 'ABCDEFGHIJ1234567890'
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# Note that Star.configure has precedence over values through with
|
12
|
+
# environment variables (see {Star::Configuration}).
|
13
|
+
#
|
14
|
+
module Config
|
15
|
+
# Yields the global configuration to the given block.
|
16
|
+
#
|
17
|
+
# @example
|
18
|
+
# Star.configure do |config|
|
19
|
+
# config.access_key_id = 'ABCDEFGHIJ1234567890'
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# @yield [Star::Configuration] The global configuration.
|
23
|
+
def configure
|
24
|
+
yield configuration if block_given?
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [Boolean] whether files are stored remotely (on S3).
|
28
|
+
def remote?
|
29
|
+
!!configuration.remote
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns the global {Star::Models::Configuration} object.
|
33
|
+
#
|
34
|
+
# While this method _can_ be used to read and write configuration settings,
|
35
|
+
# it is easier to use {Star::Config#configure} Star.configure}.
|
36
|
+
#
|
37
|
+
# @example
|
38
|
+
# Star.configuration.access_key_id = 'ABCDEFGHIJ1234567890'
|
39
|
+
#
|
40
|
+
# @return [Star::Configuration] The global configuration.
|
41
|
+
def configuration
|
42
|
+
@configuration ||= Star::Configuration.new
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# @note Config is the only module auto-loaded in the Star module,
|
47
|
+
# in order to have a syntax as easy as Star.configure
|
48
|
+
|
49
|
+
extend Config
|
50
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Star
|
2
|
+
# Provides an object to store global configuration settings.
|
3
|
+
#
|
4
|
+
# This class is typically not used directly, but by calling
|
5
|
+
# {Star::Config#configure Star.configure}, which creates and updates a single
|
6
|
+
# instance of {Star::Configuration}.
|
7
|
+
#
|
8
|
+
# @example Set the API access key id/secret access key for AWS S3:
|
9
|
+
# Star.configure do |config|
|
10
|
+
# config.access_key_id = 'ABCDEFGHIJ1234567890'
|
11
|
+
# config.secret_access_key = 'ABCDEFGHIJ1234567890'
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# @see Star::Config for more examples.
|
15
|
+
#
|
16
|
+
# An alternative way to set global configuration settings is by storing
|
17
|
+
# them in the following environment variables:
|
18
|
+
#
|
19
|
+
# * +AWS_ACCESS_KEY_ID+ to store the ACCESS KEY ID
|
20
|
+
# * +AWS_SECRET_ACCESS_KEY+ to store the Client Secret for web/device apps
|
21
|
+
# * +AWS_BUCKET+ to set the name of the S3 bucket
|
22
|
+
# * +STAR_LOCATION+ to set the path for where to upload the file to
|
23
|
+
# * +STAR_DURATION+ to set the time (in seconds) for the URL to exist for
|
24
|
+
# * +STAR_REMOTE+ to store file in the local filesystem and not remotely
|
25
|
+
# In case both methods are used together,
|
26
|
+
# {Star::Config#configure Star.configure} takes precedence.
|
27
|
+
#
|
28
|
+
# @example Set the S3 access key id and secret access key:
|
29
|
+
# ENV['AWS_ACCESS_KEY_ID'] = 'ABCDEFGHIJ1234567890'
|
30
|
+
# ENV['AWS_SECRET_ACCESS_KEY'] = 'ABCDEFGHIJ1234567890'
|
31
|
+
#
|
32
|
+
class Configuration
|
33
|
+
# @return [String] the S3 access key ID.
|
34
|
+
attr_accessor :access_key_id
|
35
|
+
|
36
|
+
# @return [String] the S3 secret access key.
|
37
|
+
attr_accessor :secret_access_key
|
38
|
+
|
39
|
+
# @return [String] the name of the S3 bucket.
|
40
|
+
attr_accessor :bucket
|
41
|
+
|
42
|
+
# @return [String] the path where remote files are uploaded to.
|
43
|
+
attr_accessor :location
|
44
|
+
|
45
|
+
# @return [Integer] the number of seconds during which the URL returned by
|
46
|
+
# calling #url on a remote file is publicly available.
|
47
|
+
attr_accessor :duration
|
48
|
+
|
49
|
+
# @return [Booelan] whether to store files remotely or locally.
|
50
|
+
attr_accessor :remote
|
51
|
+
|
52
|
+
# Initialize the global configuration settings, using the values of
|
53
|
+
# the specified following environment variables by default.
|
54
|
+
def initialize
|
55
|
+
@access_key_id = ENV['AWS_ACCESS_KEY_ID']
|
56
|
+
@secret_access_key = ENV['AWS_SECRET_ACCESS_KEY']
|
57
|
+
@bucket = ENV['AWS_BUCKET']
|
58
|
+
@location = ENV.fetch('STAR_LOCATION', '/')
|
59
|
+
@duration = ENV.fetch('STAR_DURATION', '30').to_i
|
60
|
+
@remote = %w(1 t T true TRUE).include? ENV.fetch('STAR_REMOTE', 't')
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/star/file.rb
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
require 'net/http'
|
3
|
+
require 'openssl'
|
4
|
+
require 'base64'
|
5
|
+
require 'uri'
|
6
|
+
|
7
|
+
module Star
|
8
|
+
class File
|
9
|
+
attr_reader :content_type
|
10
|
+
|
11
|
+
def initialize(options = {})
|
12
|
+
@name = options.fetch :name, 'attachment'
|
13
|
+
@content_type = options.fetch :content_type, 'application/octet-stream'
|
14
|
+
@folder = options.fetch :folder, 'attachments'
|
15
|
+
end
|
16
|
+
|
17
|
+
def open
|
18
|
+
Tempfile.open 'tmp_file' do |tmp_file|
|
19
|
+
yield tmp_file
|
20
|
+
tmp_file.flush
|
21
|
+
store tmp_file
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def url
|
26
|
+
"https://#{host}/#{bucket}#{remote_path}?#{url_params}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def path
|
30
|
+
[Star.configuration.location, @folder, @name].compact.join('/')
|
31
|
+
end
|
32
|
+
|
33
|
+
def store(tmp_file)
|
34
|
+
Star.remote? ? store_remote(tmp_file) : store_local(tmp_file)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def store_remote(tmp_file)
|
40
|
+
timestamp = Time.now.utc.strftime "%a, %d %b %Y %H:%M:%S UTC"
|
41
|
+
signature = sign "PUT\n\n#{@content_type}\n#{timestamp}"
|
42
|
+
::File.open(tmp_file) do |body|
|
43
|
+
request = put_file body, signature, timestamp
|
44
|
+
response = Net::HTTP.start(host, 443, use_ssl: true) do |http|
|
45
|
+
http.request request
|
46
|
+
end
|
47
|
+
response.error! unless response.is_a? Net::HTTPSuccess
|
48
|
+
end
|
49
|
+
sleep 3 # See https://forums.aws.amazon.com/message.jspa?messageID=370480
|
50
|
+
end
|
51
|
+
|
52
|
+
def store_local(tmp_file)
|
53
|
+
FileUtils.mkdir_p ::File.dirname(path)
|
54
|
+
FileUtils.mv tmp_file.path, path
|
55
|
+
end
|
56
|
+
|
57
|
+
def url_params
|
58
|
+
expires_at = Time.now.to_i + Star.configuration.duration
|
59
|
+
digest = OpenSSL::Digest.new 'sha1'
|
60
|
+
params = "response-content-disposition=attachment"
|
61
|
+
string = "GET\n\n\n#{expires_at}\n/#{bucket}#{remote_path}?#{params}"
|
62
|
+
hmac = OpenSSL::HMAC.digest digest, secret, string
|
63
|
+
code = escape Base64.encode64(hmac)
|
64
|
+
|
65
|
+
"#{params}&AWSAccessKeyId=#{key}&Expires=#{expires_at}&Signature=#{code}"
|
66
|
+
end
|
67
|
+
|
68
|
+
def put_file(body, signature, timestamp)
|
69
|
+
Net::HTTP::Put.new("/#{bucket}#{remote_path}").tap do |request|
|
70
|
+
request.body_stream = body
|
71
|
+
request.initialize_http_header 'Content-Length' => body.size.to_s
|
72
|
+
request.add_field 'Host', host
|
73
|
+
request.add_field 'Date', timestamp
|
74
|
+
request.add_field 'Content-Type', @content_type
|
75
|
+
request.add_field 'Authorization', "AWS #{key}:#{signature}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def sign(action)
|
80
|
+
digest = OpenSSL::Digest.new 'sha1'
|
81
|
+
string = "#{action}\n/#{bucket}#{remote_path}"
|
82
|
+
Base64.strict_encode64 OpenSSL::HMAC.digest(digest, secret, string)
|
83
|
+
end
|
84
|
+
|
85
|
+
def escape(string)
|
86
|
+
s = {'+' => "%2B", '=' => "%3D", '?' => '%3F', '@' => '%40', '$' => '%24',
|
87
|
+
'&' => '%26', ',' => '%2C', '/' => '%2F', ':' => '%3A', ';' => '%3B'}
|
88
|
+
URI.escape(string.strip).gsub(/./) {|c| s.fetch(c, c)}
|
89
|
+
end
|
90
|
+
|
91
|
+
def host
|
92
|
+
"s3.amazonaws.com"
|
93
|
+
end
|
94
|
+
|
95
|
+
def remote_path
|
96
|
+
URI.escape path
|
97
|
+
end
|
98
|
+
|
99
|
+
def key
|
100
|
+
Star.configuration.access_key_id
|
101
|
+
end
|
102
|
+
|
103
|
+
def secret
|
104
|
+
Star.configuration.secret_access_key
|
105
|
+
end
|
106
|
+
|
107
|
+
def bucket
|
108
|
+
Star.configuration.bucket
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
data/lib/star/version.rb
CHANGED
data/star.gemspec
CHANGED
@@ -6,11 +6,12 @@ require 'star/version'
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = 'star'
|
8
8
|
spec.version = Star::VERSION
|
9
|
-
spec.authors = ['claudiob']
|
10
|
-
spec.email = ['claudiob@gmail.com']
|
11
|
-
|
12
|
-
spec.
|
13
|
-
|
9
|
+
spec.authors = ['claudiob', 'Jeremy Cohen Hoffing']
|
10
|
+
spec.email = ['claudiob@gmail.com', 'jcohenhoffing@gmail.com']
|
11
|
+
spec.summary = %q{Write files to S3, read them with expiring URLs}
|
12
|
+
spec.description = %q{Star provides a File class to write files to S3
|
13
|
+
as though they were local files, and to retrieve them from S3 with a URL
|
14
|
+
that expires after 30 seconds, so it cannot be shared publicly.}
|
14
15
|
spec.homepage = 'https://github.com/fullscreen/star'
|
15
16
|
spec.license = 'MIT'
|
16
17
|
|
@@ -21,4 +22,7 @@ Gem::Specification.new do |spec|
|
|
21
22
|
|
22
23
|
spec.add_development_dependency 'bundler', '~> 1.10'
|
23
24
|
spec.add_development_dependency 'rake', '~> 10.0'
|
25
|
+
spec.add_development_dependency 'rspec', '~> 3.3'
|
26
|
+
spec.add_development_dependency 'coveralls', '~> 0.8.2'
|
27
|
+
spec.add_development_dependency 'pry-nav', '~> 0.2.4'
|
24
28
|
end
|
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: star
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- claudiob
|
8
|
+
- Jeremy Cohen Hoffing
|
8
9
|
autorequire:
|
9
10
|
bindir: exe
|
10
11
|
cert_chain: []
|
11
|
-
date: 2015-
|
12
|
+
date: 2015-10-26 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: bundler
|
@@ -38,23 +39,73 @@ dependencies:
|
|
38
39
|
- - "~>"
|
39
40
|
- !ruby/object:Gem::Version
|
40
41
|
version: '10.0'
|
41
|
-
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rspec
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '3.3'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '3.3'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: coveralls
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 0.8.2
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.8.2
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: pry-nav
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 0.2.4
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: 0.2.4
|
84
|
+
description: |-
|
85
|
+
Star provides a File class to write files to S3
|
86
|
+
as though they were local files, and to retrieve them from S3 with a URL
|
87
|
+
that expires after 30 seconds, so it cannot be shared publicly.
|
42
88
|
email:
|
43
89
|
- claudiob@gmail.com
|
90
|
+
- jcohenhoffing@gmail.com
|
44
91
|
executables: []
|
45
92
|
extensions: []
|
46
93
|
extra_rdoc_files: []
|
47
94
|
files:
|
48
95
|
- ".gitignore"
|
96
|
+
- ".rspec"
|
49
97
|
- ".travis.yml"
|
50
|
-
-
|
98
|
+
- CHANGELOG.md
|
51
99
|
- Gemfile
|
52
|
-
- LICENSE
|
100
|
+
- MIT-LICENSE
|
53
101
|
- README.md
|
54
102
|
- Rakefile
|
55
103
|
- bin/console
|
56
104
|
- bin/setup
|
57
105
|
- lib/star.rb
|
106
|
+
- lib/star/config.rb
|
107
|
+
- lib/star/configuration.rb
|
108
|
+
- lib/star/file.rb
|
58
109
|
- lib/star/version.rb
|
59
110
|
- star.gemspec
|
60
111
|
homepage: https://github.com/fullscreen/star
|
@@ -80,6 +131,5 @@ rubyforge_project:
|
|
80
131
|
rubygems_version: 2.4.5.1
|
81
132
|
signing_key:
|
82
133
|
specification_version: 4
|
83
|
-
summary:
|
134
|
+
summary: Write files to S3, read them with expiring URLs
|
84
135
|
test_files: []
|
85
|
-
has_rdoc:
|
data/CODE_OF_CONDUCT.md
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
# Contributor Code of Conduct
|
2
|
-
|
3
|
-
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
4
|
-
|
5
|
-
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
|
6
|
-
|
7
|
-
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
|
8
|
-
|
9
|
-
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
|
10
|
-
|
11
|
-
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
|
12
|
-
|
13
|
-
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
|