cloudimage 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -1
- data/README.md +55 -8
- data/lib/cloudimage/client.rb +1 -0
- data/lib/cloudimage/custom_helpers.rb +6 -0
- data/lib/cloudimage/refinements.rb +23 -0
- data/lib/cloudimage/security.rb +56 -0
- data/lib/cloudimage/uri.rb +34 -27
- data/lib/cloudimage/version.rb +1 -1
- metadata +32 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 06d221bc041ab617d9997d66e6d2c4b9f03dcbdcbbf4c05cb6b54f1c66f7c5f1
|
4
|
+
data.tar.gz: 2ed732e2099d6a3b1a9649da9840b303bef144f43b0cd2801e09f6d080361c28
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5385f01daa66e04d394c8cc2d0257f367ba5f18f3f553ccc71a7341c4149975c94a5b707305cf3e3a6c93a6ff5a2346a459c623d7ca80aff35ca65c886dd0cb9
|
7
|
+
data.tar.gz: f4130b0bf5d7b40325e5a04f69a5e8dcbe117519369a517d4665788c3c78d0e84ba976d1c542bf0a06a38082893dd2342e695b8906e2ef9df54df0f807a389e9
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,17 @@
|
|
1
|
-
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## [Unreleased](https://github.com/scaleflex/cloudimage-rb/tree/HEAD)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/scaleflex/cloudimage-rb/compare/v0.2.1...HEAD)
|
6
|
+
|
7
|
+
**Closed issues:**
|
8
|
+
|
9
|
+
- Add automatic changelog generation [\#11](https://github.com/scaleflex/cloudimage-rb/issues/11)
|
10
|
+
|
11
|
+
**Merged pull requests:**
|
12
|
+
|
13
|
+
- Use changelog generation [\#16](https://github.com/scaleflex/cloudimage-rb/pull/16) ([janklimo](https://github.com/janklimo))
|
14
|
+
- Add test coverage with SimpleCov [\#9](https://github.com/scaleflex/cloudimage-rb/pull/9) ([janklimo](https://github.com/janklimo))
|
2
15
|
|
3
16
|
## 0.2.1 (2020-06-29)
|
4
17
|
|
@@ -23,3 +36,6 @@
|
|
23
36
|
|
24
37
|
- Set up Github actions for CI.
|
25
38
|
[#1](https://github.com/scaleflex/cloudimage-rb/pull/1) (@janklimo)
|
39
|
+
|
40
|
+
|
41
|
+
\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
|
data/README.md
CHANGED
@@ -15,11 +15,13 @@ Supports Ruby `2.4` and above, `JRuby`, and `TruffleRuby`.
|
|
15
15
|
- [Aliases](#aliases)
|
16
16
|
- [Custom helpers](#custom-helpers)
|
17
17
|
- [Security](#security)
|
18
|
+
- [URL signature](#url-signature)
|
19
|
+
- [URL sealing](#url-sealing)
|
18
20
|
- [Development](#development)
|
19
|
-
- [TODOs](#todos)
|
20
21
|
- [Contributing](#contributing)
|
21
22
|
- [License](#license)
|
22
23
|
- [Code of Conduct](#code-of-conduct)
|
24
|
+
- [Showcase](#showcase)
|
23
25
|
|
24
26
|
## Installation
|
25
27
|
|
@@ -59,6 +61,7 @@ Cloudimage client accepts the following options:
|
|
59
61
|
| `salt` | No | See [Security](#security). |
|
60
62
|
| `signature_length` | No | Integer value in the range `6..40`. Defaults to 18. |
|
61
63
|
| `api_version` | No | Defaults to the current stable version. |
|
64
|
+
| `sign_urls` | No | Defaults to `true`. See [Security](#security). |
|
62
65
|
|
63
66
|
Calling `path` on the client object returns an instance of `Cloudimage::URI`.
|
64
67
|
It accepts path to the image as a string and we we will use it to build
|
@@ -121,6 +124,8 @@ For a list of custom helpers available to you, please consult
|
|
121
124
|
|
122
125
|
### Security
|
123
126
|
|
127
|
+
#### URL signature
|
128
|
+
|
124
129
|
If `salt` is defined, all URLs will be signed.
|
125
130
|
|
126
131
|
You can control the length of the generated signature by specifying `signature_length`
|
@@ -133,6 +138,46 @@ uri.w(200).h(400).to_url
|
|
133
138
|
# => "https://mysecrettoken.cloudimg.io/v7/assets/image.png?h=400&w=200&ci_sign=79cfbc458b"
|
134
139
|
```
|
135
140
|
|
141
|
+
#### URL sealing
|
142
|
+
|
143
|
+
Whereas URL signatures let you protect your URL from any kind of
|
144
|
+
tampering, URL sealing protects the params you specify while making
|
145
|
+
it possible to append additional params on the fly.
|
146
|
+
|
147
|
+
This is useful when working with Cloudimage's
|
148
|
+
[responsive frontend libraries](https://docs.cloudimage.io/go/cloudimage-documentation-v7/en/responsive-images).
|
149
|
+
A common use case would be sealing your watermark but letting the
|
150
|
+
React client request the best possible width.
|
151
|
+
|
152
|
+
To seal your URLs, initialize client with `salt` and set
|
153
|
+
`sign_urls` to `false`. `signature_length` setting is applied
|
154
|
+
to control the length of the generated `ci_seal` value.
|
155
|
+
|
156
|
+
Use the `seal_params` helper to specify which params to seal
|
157
|
+
as a list of arguments. These could be symbols or strings.
|
158
|
+
|
159
|
+
```ruby
|
160
|
+
client = Cloudimage::Client.new(token: 'demoseal', salt: 'test', sign_urls: false)
|
161
|
+
|
162
|
+
client
|
163
|
+
.path('/sample.li/birds.jpg')
|
164
|
+
.f('bright:10,contrast:20')
|
165
|
+
.w(300)
|
166
|
+
.h(400)
|
167
|
+
.seal_params(:w, :f)
|
168
|
+
.to_url
|
169
|
+
# => "https://demoseal.cloudimg.io/v7/sample.li/birds.jpg?ci_eqs=Zj1icmlnaHQlM0ExMCUyQ2NvbnRyYXN0JTNBMjAmdz0zMDA&ci_seal=67dd8cc44f6ba44ee5&h=400"
|
170
|
+
|
171
|
+
# Alternative approach:
|
172
|
+
client
|
173
|
+
.path('/sample.li/birds.jpg')
|
174
|
+
.to_url(f: 'bright:10,contrast:20', w: 300, h: 400, seal_params: [:w, :f])
|
175
|
+
# => "https://demoseal.cloudimg.io/v7/sample.li/birds.jpg?ci_eqs=Zj1icmlnaHQlM0ExMCUyQ2NvbnRyYXN0JTNBMjAmdz0zMDA&ci_seal=67dd8cc44f6ba44ee5&h=400"
|
176
|
+
```
|
177
|
+
|
178
|
+
This approach protects `w` and `f` values from being edited but
|
179
|
+
makes it possible to freely modify the value of `h`.
|
180
|
+
|
136
181
|
## Development
|
137
182
|
|
138
183
|
After checking out the repo, run `bin/setup` to install dependencies.
|
@@ -140,13 +185,6 @@ Then, run `bundle exec rake` to run the tests. You can also run
|
|
140
185
|
`bin/console` for an interactive prompt that will allow you to
|
141
186
|
experiment.
|
142
187
|
|
143
|
-
### TODOs
|
144
|
-
|
145
|
-
- URL sealing
|
146
|
-
- Add support for custom CNAMEs
|
147
|
-
- `srcset` generation
|
148
|
-
- Purge cache API
|
149
|
-
|
150
188
|
## Contributing
|
151
189
|
|
152
190
|
Bug reports and pull requests are welcome. This project is intended
|
@@ -164,3 +202,12 @@ The gem is available as open source under the terms of the
|
|
164
202
|
Everyone interacting with the project's codebase, issues, and pull
|
165
203
|
requests is expected to follow the
|
166
204
|
[code of conduct](https://github.com/scaleflex/cloudimage-rb/blob/master/CODE_OF_CONDUCT.md).
|
205
|
+
|
206
|
+
## Showcase
|
207
|
+
|
208
|
+
Among others, `cloudimage` is used to power the following apps:
|
209
|
+
|
210
|
+
- [Robin PRO](https://apps.shopify.com/robin-pro-image-gallery) - Fast, beautiful, mobile-friendly image galleries for Shopify stores.
|
211
|
+
|
212
|
+
Using this gem in your app? Let us know in [this issue](https://github.com/scaleflex/cloudimage-rb/issues/8)
|
213
|
+
so that we can feature it.
|
data/lib/cloudimage/client.rb
CHANGED
@@ -5,5 +5,11 @@ module Cloudimage
|
|
5
5
|
def positionable_crop(origin_x:, origin_y:, width:, height:)
|
6
6
|
tl_px(origin_x, origin_y).br_px(origin_x + width, origin_y + height)
|
7
7
|
end
|
8
|
+
|
9
|
+
def seal_params(*query_params)
|
10
|
+
# URI#query_values returns hash where keys are strings.
|
11
|
+
sealed_params.merge(query_params.map(&:to_s))
|
12
|
+
self
|
13
|
+
end
|
8
14
|
end
|
9
15
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cloudimage
|
4
|
+
module Refinements
|
5
|
+
unless {}.respond_to?(:slice)
|
6
|
+
refine Hash do
|
7
|
+
def slice(*keys)
|
8
|
+
keys.each_with_object({}) do |k, acc|
|
9
|
+
acc[k] = self[k] if key?(k)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
unless ''.respond_to?(:delete_prefix)
|
16
|
+
refine String do
|
17
|
+
def delete_prefix(prefix)
|
18
|
+
sub(/\A#{prefix}/, '')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'digest'
|
4
|
+
require 'base64'
|
5
|
+
|
6
|
+
require_relative 'refinements'
|
7
|
+
|
8
|
+
module Cloudimage
|
9
|
+
class Security
|
10
|
+
using Refinements
|
11
|
+
|
12
|
+
attr_reader :uri, :config
|
13
|
+
|
14
|
+
def initialize(uri, **config)
|
15
|
+
@uri = uri
|
16
|
+
@config = config
|
17
|
+
end
|
18
|
+
|
19
|
+
def sign_url(request_uri)
|
20
|
+
query = uri.query_values || {}
|
21
|
+
uri.query_values = query.merge(ci_sign: signature(request_uri))
|
22
|
+
end
|
23
|
+
|
24
|
+
def seal_url(path, sealed_params)
|
25
|
+
query = uri.query_values || {}
|
26
|
+
sealed_query = query.slice(*sealed_params)
|
27
|
+
query.keep_if { |k, _| !sealed_query.key?(k) }
|
28
|
+
eqs = eqs(sealed_query)
|
29
|
+
query[:ci_eqs] = eqs unless eqs.empty?
|
30
|
+
query[:ci_seal] = seal(path, eqs)
|
31
|
+
uri.query_values = query
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def signature(request_uri)
|
37
|
+
digest = Digest::SHA1.hexdigest(config[:salt] + request_uri)
|
38
|
+
trim(digest, config[:signature_length])
|
39
|
+
end
|
40
|
+
|
41
|
+
def eqs(query_params)
|
42
|
+
uri = Addressable::URI.new
|
43
|
+
uri.query_values = query_params
|
44
|
+
Base64.urlsafe_encode64(uri.query, padding: false)
|
45
|
+
end
|
46
|
+
|
47
|
+
def seal(path, eqs)
|
48
|
+
digest = Digest::SHA1.hexdigest(path + eqs + config[:salt])
|
49
|
+
trim(digest, config[:signature_length])
|
50
|
+
end
|
51
|
+
|
52
|
+
def trim(signature, length)
|
53
|
+
signature[0, length]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/cloudimage/uri.rb
CHANGED
@@ -1,31 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'digest'
|
4
|
-
|
5
3
|
require_relative 'params'
|
6
4
|
require_relative 'custom_helpers'
|
5
|
+
require_relative 'security'
|
6
|
+
require_relative 'refinements'
|
7
7
|
|
8
8
|
module Cloudimage
|
9
9
|
class URI
|
10
|
+
using Refinements
|
11
|
+
|
10
12
|
include Params
|
11
13
|
include CustomHelpers
|
12
14
|
|
13
|
-
attr_reader :uri, :params, :config
|
15
|
+
attr_reader :path, :uri, :params, :config, :sealed_params
|
14
16
|
|
15
17
|
def initialize(path, **config)
|
16
18
|
@config = config
|
17
19
|
@params = {}
|
18
|
-
@
|
20
|
+
@sealed_params = Set.new
|
21
|
+
@path = ensure_path_format(path)
|
22
|
+
@uri = build_uri
|
19
23
|
end
|
20
24
|
|
21
25
|
PARAMS.each do |param|
|
22
26
|
define_method param do |*args|
|
23
|
-
|
24
|
-
|
25
|
-
else
|
26
|
-
# Flag params don't need to pass in arguments.
|
27
|
-
@params[param] = 1
|
28
|
-
end
|
27
|
+
# Flag params don't need to pass in arguments.
|
28
|
+
params[param] = args.any? ? args.join(',') : 1
|
29
29
|
self
|
30
30
|
end
|
31
31
|
end
|
@@ -36,43 +36,50 @@ module Cloudimage
|
|
36
36
|
|
37
37
|
def to_url(**extra_params)
|
38
38
|
set_uri_params(**extra_params)
|
39
|
-
|
39
|
+
secure_url
|
40
|
+
uri.to_s
|
40
41
|
end
|
41
42
|
|
42
43
|
private
|
43
44
|
|
44
|
-
def
|
45
|
+
def site
|
45
46
|
"https://#{config[:token]}.cloudimg.io"
|
46
47
|
end
|
47
48
|
|
48
|
-
def
|
49
|
-
"
|
49
|
+
def api_version
|
50
|
+
"/#{config[:api_version]}"
|
50
51
|
end
|
51
52
|
|
52
|
-
def
|
53
|
-
|
54
|
-
|
53
|
+
def ensure_path_format(path)
|
54
|
+
path.start_with?('/') ? path : "/#{path}"
|
55
|
+
end
|
56
|
+
|
57
|
+
def request_uri
|
58
|
+
uri.request_uri.delete_prefix(api_version)
|
59
|
+
end
|
60
|
+
|
61
|
+
def build_uri
|
62
|
+
Addressable::URI.parse(site + api_version + path)
|
55
63
|
end
|
56
64
|
|
57
65
|
def set_uri_params(**extra_params)
|
66
|
+
seal_params(*extra_params.delete(:seal_params))
|
58
67
|
url_params = params.merge(**extra_params)
|
59
68
|
return unless url_params.any?
|
60
69
|
|
61
70
|
uri.query_values = url_params
|
62
71
|
end
|
63
72
|
|
64
|
-
def
|
65
|
-
|
66
|
-
|
67
|
-
return url if config[:salt].nil?
|
73
|
+
def secure_url
|
74
|
+
return uri.to_s if config[:salt].nil?
|
68
75
|
|
69
|
-
|
70
|
-
end
|
76
|
+
security = Security.new(uri, **config)
|
71
77
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
78
|
+
if config[:sign_urls]
|
79
|
+
security.sign_url(request_uri)
|
80
|
+
else
|
81
|
+
security.seal_url(path, sealed_params)
|
82
|
+
end
|
76
83
|
end
|
77
84
|
end
|
78
85
|
end
|
data/lib/cloudimage/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudimage
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jan Klimo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -24,6 +24,34 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '2.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: github_changelog_generator
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.15.2
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.15.2
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.13'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.13'
|
27
55
|
description: Fast and easy image resizing, transformation, and acceleration in the
|
28
56
|
Cloud.
|
29
57
|
email:
|
@@ -41,6 +69,8 @@ files:
|
|
41
69
|
- lib/cloudimage/client.rb
|
42
70
|
- lib/cloudimage/custom_helpers.rb
|
43
71
|
- lib/cloudimage/params.rb
|
72
|
+
- lib/cloudimage/refinements.rb
|
73
|
+
- lib/cloudimage/security.rb
|
44
74
|
- lib/cloudimage/uri.rb
|
45
75
|
- lib/cloudimage/version.rb
|
46
76
|
homepage: https://github.com/scaleflex/cloudimage-rb
|