Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

- Do not modify original url when using cdn

### features

- filepicker_image_tag now works with policies

## 1.1.0 (March 30, 2014)

### features
Expand Down
30 changes: 29 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,35 @@ of an iframe on the page.
* services - What services your users can upload to. Ex: "BOX, COMPUTER, FACEBOOK".
* save_as_name - A recommended file name. The user can override this.

### Demo
### Policy

To use the [filepicker policies](https://developers.inkfilepicker.com/docs/security/) follow this instructions.

Set your Secret Key in `config/application.rb`

```ruby
config.filepicker_rails.secret_key = "Your filepicker.io Secret Key"
```

### Expiry time

By default the expiry time is 10 minutes. If you need to change the expiry time this should be an integer and it is expressed in seconds since the [Epoch](http://en.wikipedia.org/wiki/Unix_time).

So you can do something like that to set the expiry time to 5 minutes.

```ruby
config.filepicker_rails.expiry = -> { (Time.zone.now + 5.minutes).to_i }
```

If you need always the same url, a static expiry time, to do some cache. You can set a date starting of the Epoch.

```ruby
-> { 100.years.since(Time.at(0)).to_i }
```

The argument need to be a [callable](http://www.rubytapas.com/episodes/35-Callable).

## Demo

See a simple demo app [repo](https://github.com/maxtilford/filepicker-rails-demo)

Expand Down
64 changes: 56 additions & 8 deletions app/helpers/filepicker_rails/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,66 @@ def filepicker_image_tag(url, image_options={}, image_tag_options={})
# and horizontal with a comma. The default behavior
# is bottom,right
def filepicker_image_url(url, options = {})
query_params = options.slice(:w, :h, :fit, :align, :rotate, :cache, :crop, :format, :quality, :watermark, :watersize, :waterposition).to_query
FilepickerImageUrl.new(url, options).execute
end

class FilepickerImageUrl

if ::Rails.application.config.filepicker_rails.cdn_host
uri = URI.parse(url)
url = url.gsub("#{uri.scheme}://#{uri.host}", ::Rails.application.config.filepicker_rails.cdn_host)
CONVERT_OPTIONS = [:w, :h, :fit, :align, :rotate, :crop, :format,
:quality, :watermark, :watersize, :waterposition]
VALID_OPTIONS = CONVERT_OPTIONS + [:cache]

def initialize(url, options = {})
@url, @options = url, options
end

if query_params.blank?
url
else
[url, "/convert?", query_params].join
def execute
url_with_path = if convert_options.any?
"#{cdn_url}/convert"
else
cdn_url
end

query_params = all_options.merge(policy_config).to_query

[url_with_path, query_params.presence].compact.join('?')
end

private

attr_reader :url, :options

def all_options
options.select { |option| VALID_OPTIONS.include?(option) }
end

def convert_options
options.select { |option| CONVERT_OPTIONS.include?(option) }
end

def cdn_host
::Rails.application.config.filepicker_rails.cdn_host
end

def cdn_url
if cdn_host
uri = URI.parse(url)
url.gsub("#{uri.scheme}://#{uri.host}", cdn_host)
else
url
end
end

def policy_config
return {} unless ::Rails.application.config.filepicker_rails.secret_key.present?
grant = Policy.new
grant.call = [:read, :convert]

{
'policy' => grant.policy,
'signature' => grant.signature
}
end
end
end
end
2 changes: 1 addition & 1 deletion filepicker_rails.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Gem::Specification.new do |s|

s.add_development_dependency 'coveralls'
s.add_development_dependency 'sqlite3'
s.add_development_dependency 'rspec-rails'
s.add_development_dependency 'rspec-rails', '2.99'
s.add_development_dependency 'timecop'
s.add_development_dependency 'appraisal'
s.add_development_dependency 'capybara'
Expand Down
11 changes: 8 additions & 3 deletions lib/filepicker_rails/configuration.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
module FilepickerRails
class Configuration
attr_writer :api_key, :default_expiry
attr_writer :api_key
attr_accessor :secret_key, :cdn_host

def api_key
@api_key or raise "Set config.filepicker_rails.api_key"
end

def default_expiry
@default_expiry ||= 600
def expiry=(expiry)
raise ArgumentError, 'Must be a callable' unless expiry.respond_to?(:call)
@expiry = expiry
end

def expiry
@expiry ||= -> { Time.zone.now.to_i + 600 }
end
end
end
2 changes: 1 addition & 1 deletion lib/filepicker_rails/policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def signature
def json_policy
hash = Hash.new

@expiry ||= Time.now.to_i + ::Rails.application.config.filepicker_rails.default_expiry
@expiry ||= ::Rails.application.config.filepicker_rails.expiry.call

[:expiry, :call, :handle, :maxsize, :minsize, :path].each do |input|
hash[input] = send(input) unless send(input).nil?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,6 @@
expect(filepicker_image_url("foo", rotate: 'exif')).to eq('foo/convert?rotate=exif')
end

it "have correct url with 'cache'" do
expect(filepicker_image_url("foo", cache: true)).to eq('foo/convert?cache=true')
end

it "have correct url with 'crop'" do
expect(filepicker_image_url("foo", crop: '20,30,400,200')).to eq('foo/convert?crop=20%2C30%2C400%2C200')
Expand All @@ -150,6 +147,18 @@
it "have correct url with 'waterposition'" do
expect(filepicker_image_url("foo", waterposition: 'top')).to eq('foo/convert?waterposition=top')
end

describe 'cache' do

it "have correct url with 'cache' only" do
expect(filepicker_image_url("foo", cache: true)).to eq('foo?cache=true')
end

it "have correct url with 'cache' and convert option" do
url = 'foo/convert?align=faces&cache=true'
expect(filepicker_image_url("foo", cache: true, align: 'faces')).to eq(url)
end
end
end

context "with cdn host" do
Expand All @@ -172,5 +181,32 @@
end.to_not change { url }
end
end

context 'with policy' do

before do
Timecop.freeze(Time.zone.parse("2012-09-19 12:59:27"))
Rails.application.config.filepicker_rails.secret_key = 'filepicker123secretkey'
end

after do
Timecop.return
Rails.application.config.filepicker_rails.secret_key = nil
end

it 'have policy and signature' do
url = 'foo?policy=eyJleHBpcnkiOjEzNDgwNjAxNjcsImNhbGwiOlsicmVhZCIsImNvbnZlcnQiXX0%3D' \
'&signature=4562a7e728aa0e53d82c20a97e4f01103dd127724edce631c3f4ada70922eecd'
expect(filepicker_image_url('foo')).to eq(url)
end

it 'have policy and signature when have some convert option' do
url = 'foo/convert' \
'?policy=eyJleHBpcnkiOjEzNDgwNjAxNjcsImNhbGwiOlsicmVhZCIsImNvbnZlcnQiXX0%3D' \
'&quality=80' \
'&signature=4562a7e728aa0e53d82c20a97e4f01103dd127724edce631c3f4ada70922eecd'
expect(filepicker_image_url('foo', quality: 80)).to eq(url)
end
end
end
end
22 changes: 15 additions & 7 deletions spec/lib/configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,16 @@
end
end

describe "#default_expiry=" do
describe "#expiry=" do

it "respond to default_expiry=" do
expect(configuration).to respond_to(:default_expiry=)
it "respond to expiry=" do
expect(configuration).to respond_to(:expiry=)
end

it 'raises error if not receive a callable' do
expect do
configuration.expiry = 12
end.to raise_error(ArgumentError, 'Must be a callable')
end
end

Expand All @@ -49,15 +55,17 @@
end
end

describe "#default_expiry" do
describe "#expiry" do

it "have defined value" do
configuration.default_expiry = 450
expect(configuration.default_expiry).to eq(450)
configuration.expiry = -> { 450 }
expect(configuration.expiry.call).to eq(450)
end

it "have a default value" do
expect(configuration.default_expiry).to eq(600)
Timecop.freeze(Time.zone.parse("2012-09-19 12:59:27")) do
expect(configuration.expiry.call).to eq(1348060167)
end
end
end

Expand Down