cloudimage 0.1.0 → 0.5.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 +42 -2
- data/README.md +144 -11
- data/lib/cloudimage.rb +0 -1
- data/lib/cloudimage/client.rb +33 -11
- data/lib/cloudimage/custom_helpers.rb +6 -0
- data/lib/cloudimage/invalidation.rb +50 -0
- data/lib/cloudimage/params.rb +28 -0
- data/lib/cloudimage/refinements.rb +47 -0
- data/lib/cloudimage/security.rb +56 -0
- data/lib/cloudimage/uri.rb +69 -15
- metadata +37 -7
- data/lib/cloudimage/version.rb +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 67e8f90abd62c87ace671bfb901dc04fe4acd45eb4bdef4d85a5b3208d0b3b3e
|
4
|
+
data.tar.gz: 683086c1cd095ee0121a17d30d498f11a29d558b6e855b55b5d3a4232e312b08
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b409ab0b86ba4b26c4b0e2d8d36b201f1383bdeaa67e729982eecf7ff3ad0ab142e876cb5c3294cb81ea28b985da3903f4a947f0b300e08938dd806cab1fa842
|
7
|
+
data.tar.gz: 4bd6d593d935c1a74cf1a6a5d440337937c88dc530d57ef71f3bc3b38b8a902bd3088b513df13700cef2c25d6d0901ac3381c5aba2dddcb967ec43f04fa7f639
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,43 @@
|
|
1
|
-
|
1
|
+
# Changelog
|
2
2
|
|
3
|
-
## 0.
|
3
|
+
## [v0.4.0](https://github.com/scaleflex/cloudimage-rb/tree/v0.4.0) (2020-07-19)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/scaleflex/cloudimage-rb/compare/v0.3.0...v0.4.0)
|
6
|
+
|
7
|
+
**Implemented enhancements:**
|
8
|
+
|
9
|
+
- Add support for aliases [\#20](https://github.com/scaleflex/cloudimage-rb/pull/20) ([janklimo](https://github.com/janklimo))
|
10
|
+
|
11
|
+
## [v0.3.0](https://github.com/scaleflex/cloudimage-rb/tree/v0.3.0) (2020-07-09)
|
12
|
+
|
13
|
+
[Full Changelog](https://github.com/scaleflex/cloudimage-rb/compare/v0.2.1...v0.3.0)
|
14
|
+
|
15
|
+
**Implemented enhancements:**
|
16
|
+
|
17
|
+
- Introduce URL sealing [\#10](https://github.com/scaleflex/cloudimage-rb/pull/10) ([janklimo](https://github.com/janklimo))
|
18
|
+
- Add support for image resizing [\#2](https://github.com/scaleflex/cloudimage-rb/pull/2) ([janklimo](https://github.com/janklimo))
|
19
|
+
|
20
|
+
**Merged pull requests:**
|
21
|
+
|
22
|
+
- Use changelog generation [\#16](https://github.com/scaleflex/cloudimage-rb/pull/16) ([janklimo](https://github.com/janklimo))
|
23
|
+
- Add test coverage with SimpleCov [\#9](https://github.com/scaleflex/cloudimage-rb/pull/9) ([janklimo](https://github.com/janklimo))
|
24
|
+
|
25
|
+
## 0.2.1 (2020-06-29)
|
26
|
+
|
27
|
+
- Include `force_download` param.
|
28
|
+
|
29
|
+
## 0.2.0 (2020-06-28)
|
30
|
+
|
31
|
+
- URL signatures.
|
32
|
+
[#6](https://github.com/scaleflex/cloudimage-rb/pull/6) (@janklimo)
|
33
|
+
- Added the remaining API params so that they can be used as helpers.
|
34
|
+
[#7](https://github.com/scaleflex/cloudimage-rb/pull/7) (@janklimo)
|
35
|
+
- We don't run `rubocop` on `truffleruby` anymore.
|
36
|
+
It [is not officially supported](https://docs.rubocop.org/rubocop/compatibility.html)
|
37
|
+
and leads to [unexpected issues](https://github.com/scaleflex/cloudimage-rb/runs/815208955?check_suite_focus=true).
|
38
|
+
[#7](https://github.com/scaleflex/cloudimage-rb/pull/7) (@janklimo)
|
39
|
+
|
40
|
+
## 0.1.0 (2020-06-09)
|
4
41
|
|
5
42
|
- Introduce base models: `Cloudimage::Client`, and `Cloudimage::URI`. Generate
|
6
43
|
URLs via `to_url` method. Add support for image resizing params.
|
@@ -8,3 +45,6 @@
|
|
8
45
|
|
9
46
|
- Set up Github actions for CI.
|
10
47
|
[#1](https://github.com/scaleflex/cloudimage-rb/pull/1) (@janklimo)
|
48
|
+
|
49
|
+
|
50
|
+
\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# cloudimage
|
2
2
|
|
3
|
-

|
3
|
+
[](https://badge.fury.io/rb/cloudimage) 
|
4
4
|
|
5
5
|
`cloudimage` is the official Ruby API wrapper for
|
6
6
|
[Cloudimage's API](https://docs.cloudimage.io/go/cloudimage-documentation-v7/en/introduction).
|
@@ -12,12 +12,18 @@ Supports Ruby `2.4` and above, `JRuby`, and `TruffleRuby`.
|
|
12
12
|
- [Usage](#usage)
|
13
13
|
- [Hash of params](#hash-of-params)
|
14
14
|
- [Chainable helpers](#chainable-helpers)
|
15
|
-
- [
|
15
|
+
- [Method aliases](#method-aliases)
|
16
16
|
- [Custom helpers](#custom-helpers)
|
17
|
+
- [URL aliases](#url-aliases)
|
18
|
+
- [CNAME](#cname)
|
19
|
+
- [Security](#security)
|
20
|
+
- [URL signature](#url-signature)
|
21
|
+
- [URL sealing](#url-sealing)
|
22
|
+
- [Invalidation API](#invalidation-api)
|
17
23
|
- [Development](#development)
|
18
24
|
- [Contributing](#contributing)
|
19
25
|
- [License](#license)
|
20
|
-
- [
|
26
|
+
- [Showcase](#showcase)
|
21
27
|
|
22
28
|
## Installation
|
23
29
|
|
@@ -37,7 +43,7 @@ Or install it yourself as:
|
|
37
43
|
|
38
44
|
## Usage
|
39
45
|
|
40
|
-
The
|
46
|
+
The most common way to use Cloudimage is by means of your customer token. You can
|
41
47
|
find it within your Admin interface:
|
42
48
|
|
43
49
|

|
@@ -49,6 +55,18 @@ object:
|
|
49
55
|
client = Cloudimage::Client.new(token: 'mysecrettoken')
|
50
56
|
```
|
51
57
|
|
58
|
+
Cloudimage client accepts the following options:
|
59
|
+
|
60
|
+
| Option | Type | Additional info |
|
61
|
+
| ------------------ | ------- | ------------------------------------------------------------- |
|
62
|
+
| `token` | string | Required if `cname` is missing. |
|
63
|
+
| `cname` | string | Required if `token` is missing. See [CNAME](#cname). |
|
64
|
+
| `salt` | string | Optional. See [Security](#security). |
|
65
|
+
| `signature_length` | integer | Optional. Integer value in the range `6..40`. Defaults to 18. |
|
66
|
+
| `sign_urls` | boolean | Optional. Defaults to `true`. See [Security](#security). |
|
67
|
+
| `aliases` | hash | Optional. See [URL aliases](#url-aliases). |
|
68
|
+
| `api_key` | string | Optional. See [Invalidation API](#invalidation-api). |
|
69
|
+
|
52
70
|
Calling `path` on the client object returns an instance of `Cloudimage::URI`.
|
53
71
|
It accepts path to the image as a string and we we will use it to build
|
54
72
|
Cloudimage URLs.
|
@@ -90,7 +108,7 @@ uri.heigth(200).to_url
|
|
90
108
|
This is useful for catching typos and identifying deprecated methods in
|
91
109
|
case Cloudimage's API changes.
|
92
110
|
|
93
|
-
###
|
111
|
+
### Method aliases
|
94
112
|
|
95
113
|
The gem comes with a handful of useful aliases. Consult
|
96
114
|
[`Cloudimage::Params`](lib/cloudimage/params.rb) module for their full list.
|
@@ -108,6 +126,119 @@ need to accept arguments and will be translated into `param=1` in the final URL.
|
|
108
126
|
For a list of custom helpers available to you, please consult
|
109
127
|
[`Cloudimage::CustomHelpers`](lib/cloudimage/custom_helpers.rb) module.
|
110
128
|
|
129
|
+
### URL aliases
|
130
|
+
|
131
|
+
Specify [aliases](https://docs.cloudimage.io/go/cloudimage-documentation-v7/en/domains-urls/aliases)
|
132
|
+
to automatically replace parts of path with defined values. Aliases is a hash which
|
133
|
+
maps strings to be replaced with values to be used instead.
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
my_alias = 'https://store.s3-us-west-2.amazonaws.com/uploads'
|
137
|
+
client = Cloudimage::Client.new(token: 'token', aliases: { my_alias => '_uploads_' })
|
138
|
+
client.path('https://store.s3-us-west-2.amazonaws.com/uploads/image.jpg').to_url
|
139
|
+
# => "https://token.cloudimg.io/v7/_uploads_/image.jpg"
|
140
|
+
```
|
141
|
+
|
142
|
+
[URL prefix](https://docs.cloudimage.io/go/cloudimage-documentation-v7/en/domains-urls/origin-url-prefix)
|
143
|
+
is just another form of URL alias. Simply make the target value an empty string:
|
144
|
+
|
145
|
+
```ruby
|
146
|
+
prefix = 'https://store.s3-us-west-2.amazonaws.com/uploads/'
|
147
|
+
client = Cloudimage::Client.new(token: 'token', aliases: { prefix => '' })
|
148
|
+
client.path('https://store.s3-us-west-2.amazonaws.com/uploads/image.jpg').to_url
|
149
|
+
# => "https://token.cloudimg.io/v7/image.jpg"
|
150
|
+
```
|
151
|
+
|
152
|
+
### CNAME
|
153
|
+
|
154
|
+
If you have a custom CNAME configured for your account, you can
|
155
|
+
use it to initialize the client:
|
156
|
+
|
157
|
+
```ruby
|
158
|
+
client = Cloudimage::Client.new(cname: 'img.klimo.io')
|
159
|
+
client.path('/assets/image.jpg').to_url
|
160
|
+
# => 'https://img.klimo.io/v7/assets/image.jpg'
|
161
|
+
```
|
162
|
+
|
163
|
+
### Security
|
164
|
+
|
165
|
+
#### URL signature
|
166
|
+
|
167
|
+
If `salt` is defined, all URLs will be signed.
|
168
|
+
|
169
|
+
You can control the length of the generated signature by specifying `signature_length`
|
170
|
+
when initializing the client.
|
171
|
+
|
172
|
+
```ruby
|
173
|
+
client = Cloudimage::Client.new(token: 'mysecrettoken', salt: 'mysecretsalt', signature_length: 10)
|
174
|
+
uri = client.path('/assets/image.png')
|
175
|
+
uri.w(200).h(400).to_url
|
176
|
+
# => "https://mysecrettoken.cloudimg.io/v7/assets/image.png?h=400&w=200&ci_sign=79cfbc458b"
|
177
|
+
```
|
178
|
+
|
179
|
+
#### URL sealing
|
180
|
+
|
181
|
+
Whereas URL signatures let you protect your URL from any kind of
|
182
|
+
tampering, URL sealing protects the params you specify while making
|
183
|
+
it possible to append additional params on the fly.
|
184
|
+
|
185
|
+
This is useful when working with Cloudimage's
|
186
|
+
[responsive frontend libraries](https://docs.cloudimage.io/go/cloudimage-documentation-v7/en/responsive-images).
|
187
|
+
A common use case would be sealing your watermark but letting the
|
188
|
+
React client request the best possible width.
|
189
|
+
|
190
|
+
To seal your URLs, initialize client with `salt` and set
|
191
|
+
`sign_urls` to `false`. `signature_length` setting is applied
|
192
|
+
to control the length of the generated `ci_seal` value.
|
193
|
+
|
194
|
+
Use the `seal_params` helper to specify which params to seal
|
195
|
+
as a list of arguments. These could be symbols or strings.
|
196
|
+
|
197
|
+
```ruby
|
198
|
+
client = Cloudimage::Client.new(token: 'demoseal', salt: 'test', sign_urls: false)
|
199
|
+
|
200
|
+
client
|
201
|
+
.path('/sample.li/birds.jpg')
|
202
|
+
.f('bright:10,contrast:20')
|
203
|
+
.w(300)
|
204
|
+
.h(400)
|
205
|
+
.seal_params(:w, :f)
|
206
|
+
.to_url
|
207
|
+
# => "https://demoseal.cloudimg.io/v7/sample.li/birds.jpg?ci_eqs=Zj1icmlnaHQlM0ExMCUyQ2NvbnRyYXN0JTNBMjAmdz0zMDA&ci_seal=67dd8cc44f6ba44ee5&h=400"
|
208
|
+
|
209
|
+
# Alternative approach:
|
210
|
+
client
|
211
|
+
.path('/sample.li/birds.jpg')
|
212
|
+
.to_url(f: 'bright:10,contrast:20', w: 300, h: 400, seal_params: [:w, :f])
|
213
|
+
# => "https://demoseal.cloudimg.io/v7/sample.li/birds.jpg?ci_eqs=Zj1icmlnaHQlM0ExMCUyQ2NvbnRyYXN0JTNBMjAmdz0zMDA&ci_seal=67dd8cc44f6ba44ee5&h=400"
|
214
|
+
```
|
215
|
+
|
216
|
+
This approach protects `w` and `f` values from being edited but
|
217
|
+
makes it possible to freely modify the value of `h`.
|
218
|
+
|
219
|
+
### Invalidation API
|
220
|
+
|
221
|
+
To access invalidation API you'll need to initialize client with
|
222
|
+
an API key.
|
223
|
+
|
224
|
+
The provided helper methods accept any number of strings:
|
225
|
+
|
226
|
+
```ruby
|
227
|
+
client = Cloudimage::Client.new(token: 'token', api_key: 'key')
|
228
|
+
|
229
|
+
# Invalidate original
|
230
|
+
client.invalidate_original('/v7/image.jpg')
|
231
|
+
|
232
|
+
# Invalidate URLs
|
233
|
+
client.invalidate_urls('/v7/image.jpg?w=200', '/v7/image.jpg?h=300')
|
234
|
+
|
235
|
+
# Invalidate all
|
236
|
+
client.invalidate_all
|
237
|
+
```
|
238
|
+
|
239
|
+
Consult the [API docs](https://docs.cloudimage.io/go/cloudimage-documentation-v7/en/caching-acceleration/invalidation-api)
|
240
|
+
for further details.
|
241
|
+
|
111
242
|
## Development
|
112
243
|
|
113
244
|
After checking out the repo, run `bin/setup` to install dependencies.
|
@@ -124,11 +255,13 @@ are expected to adhere to the
|
|
124
255
|
|
125
256
|
## License
|
126
257
|
|
127
|
-
|
128
|
-
[MIT License](https://opensource.org/licenses/MIT).
|
258
|
+
[MIT](https://opensource.org/licenses/MIT)
|
129
259
|
|
130
|
-
##
|
260
|
+
## Showcase
|
131
261
|
|
132
|
-
|
133
|
-
|
134
|
-
[
|
262
|
+
Among others, `cloudimage` is used to power the following apps:
|
263
|
+
|
264
|
+
- [Robin PRO](https://apps.shopify.com/robin-pro-image-gallery) - Fast, beautiful, mobile-friendly image galleries for Shopify stores.
|
265
|
+
|
266
|
+
Using this gem in your app? Let us know in [this issue](https://github.com/scaleflex/cloudimage-rb/issues/8)
|
267
|
+
so that we can feature it.
|
data/lib/cloudimage.rb
CHANGED
data/lib/cloudimage/client.rb
CHANGED
@@ -1,35 +1,57 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'uri'
|
4
|
+
require_relative 'invalidation'
|
4
5
|
|
5
6
|
module Cloudimage
|
6
7
|
class InvalidConfig < StandardError; end
|
7
8
|
|
8
9
|
class Client
|
9
|
-
|
10
|
+
include Invalidation
|
10
11
|
|
11
|
-
|
12
|
+
attr_reader :config
|
12
13
|
|
13
|
-
|
14
|
-
|
14
|
+
API_VERSION = 'v7'
|
15
|
+
DEFAULT_SIGNATURE_LENGTH = 18
|
15
16
|
|
16
|
-
|
17
|
+
def initialize(**options)
|
18
|
+
@config = set_config_defaults(options)
|
19
|
+
validate_config
|
17
20
|
end
|
18
21
|
|
19
22
|
def path(path)
|
20
|
-
URI.new(
|
23
|
+
URI.new(path, **config)
|
21
24
|
end
|
22
25
|
|
23
26
|
private
|
24
27
|
|
25
|
-
def
|
26
|
-
|
28
|
+
def set_config_defaults(options)
|
29
|
+
options.tap do |config|
|
30
|
+
config[:signature_length] =
|
31
|
+
options[:signature_length] || DEFAULT_SIGNATURE_LENGTH
|
32
|
+
config[:api_version] = API_VERSION
|
33
|
+
config[:sign_urls] = options[:sign_urls].nil? ? true : false
|
34
|
+
config[:aliases] = options[:aliases] || {}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def validate_config
|
39
|
+
validate_site_config
|
40
|
+
validate_signature_length
|
41
|
+
end
|
42
|
+
|
43
|
+
def validate_site_config
|
44
|
+
return unless config[:token].nil? && config[:cname].nil?
|
45
|
+
|
46
|
+
raise InvalidConfig,
|
47
|
+
'Please specify your customer token or a custom CNAME.'
|
27
48
|
end
|
28
49
|
|
29
|
-
def
|
30
|
-
return
|
50
|
+
def validate_signature_length
|
51
|
+
return if config[:salt].nil?
|
52
|
+
return if (6..40).cover? config[:signature_length]
|
31
53
|
|
32
|
-
raise InvalidConfig, '
|
54
|
+
raise InvalidConfig, 'Signature length must be must be 6-40 characters.'
|
33
55
|
end
|
34
56
|
end
|
35
57
|
end
|
@@ -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,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'net/http'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module Cloudimage
|
7
|
+
module Invalidation
|
8
|
+
ENDPOINT = ::URI.parse('https://api.cloudimage.com/invalidate')
|
9
|
+
|
10
|
+
%i[original urls all].each do |type|
|
11
|
+
define_method "invalidate_#{type}" do |*paths|
|
12
|
+
validate_api_key
|
13
|
+
|
14
|
+
body = {
|
15
|
+
scope: type,
|
16
|
+
}
|
17
|
+
|
18
|
+
body[:urls] = paths if paths.any?
|
19
|
+
|
20
|
+
send_request(body)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def validate_api_key
|
27
|
+
return if config[:api_key]
|
28
|
+
|
29
|
+
raise InvalidConfig, 'API key is required to perform cache invalidation.'
|
30
|
+
end
|
31
|
+
|
32
|
+
def headers
|
33
|
+
{
|
34
|
+
'X-Client-Key': config[:api_key],
|
35
|
+
'Content-Type': 'application/json',
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def send_request(body)
|
40
|
+
http = Net::HTTP.new(ENDPOINT.host, ENDPOINT.port)
|
41
|
+
http.use_ssl = true
|
42
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
43
|
+
|
44
|
+
request = Net::HTTP::Post.new(ENDPOINT.path, headers)
|
45
|
+
request.body = body.to_json
|
46
|
+
|
47
|
+
http.request(request)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/cloudimage/params.rb
CHANGED
@@ -18,18 +18,46 @@ module Cloudimage
|
|
18
18
|
bg_colourise
|
19
19
|
bg_img_fit
|
20
20
|
bg_opacity
|
21
|
+
blur
|
22
|
+
blur_faces
|
21
23
|
br_px
|
24
|
+
bright
|
22
25
|
ci_info
|
26
|
+
contrast
|
27
|
+
doc_page
|
28
|
+
f
|
29
|
+
force_download
|
30
|
+
force_format
|
23
31
|
func
|
24
32
|
gravity
|
33
|
+
gray
|
34
|
+
grey
|
25
35
|
h
|
26
36
|
height
|
37
|
+
optipress
|
27
38
|
org_if_sml
|
39
|
+
p
|
40
|
+
pixelate
|
41
|
+
pixellate
|
42
|
+
process
|
43
|
+
q
|
28
44
|
r
|
45
|
+
radius
|
29
46
|
sharp
|
30
47
|
tl_px
|
31
48
|
trim
|
32
49
|
w
|
50
|
+
wat
|
51
|
+
wat_color
|
52
|
+
wat_colour
|
53
|
+
wat_url
|
54
|
+
wat_font
|
55
|
+
wat_fontsize
|
56
|
+
wat_gravity
|
57
|
+
wat_opacity
|
58
|
+
wat_pad
|
59
|
+
wat_scale
|
60
|
+
wat_text
|
33
61
|
width
|
34
62
|
].freeze
|
35
63
|
end
|
@@ -0,0 +1,47 @@
|
|
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
|
+
|
23
|
+
unless Kernel.respond_to?(:yield_self)
|
24
|
+
refine Kernel do
|
25
|
+
def yield_self
|
26
|
+
unless block_given?
|
27
|
+
return ::Enumerator.new(1) do |yielder|
|
28
|
+
yielder.yield(self)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
yield(self)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
unless Kernel.respond_to?(:then)
|
38
|
+
refine Kernel do
|
39
|
+
def then
|
40
|
+
return yield_self unless block_given?
|
41
|
+
|
42
|
+
yield_self(&::Proc.new)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
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,29 +1,33 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'set'
|
4
|
+
|
3
5
|
require_relative 'params'
|
4
6
|
require_relative 'custom_helpers'
|
7
|
+
require_relative 'security'
|
8
|
+
require_relative 'refinements'
|
5
9
|
|
6
10
|
module Cloudimage
|
7
11
|
class URI
|
12
|
+
using Refinements
|
13
|
+
|
8
14
|
include Params
|
9
15
|
include CustomHelpers
|
10
16
|
|
11
|
-
attr_reader :uri, :params
|
17
|
+
attr_reader :path, :uri, :params, :config, :sealed_params
|
12
18
|
|
13
|
-
def initialize(
|
14
|
-
|
15
|
-
@uri = Addressable::URI.parse(base_url + path)
|
19
|
+
def initialize(path, **config)
|
20
|
+
@config = config
|
16
21
|
@params = {}
|
22
|
+
@sealed_params = Set.new
|
23
|
+
@path = transform(path)
|
24
|
+
@uri = build_uri
|
17
25
|
end
|
18
26
|
|
19
27
|
PARAMS.each do |param|
|
20
28
|
define_method param do |*args|
|
21
|
-
|
22
|
-
|
23
|
-
else
|
24
|
-
# Flag params don't need to pass in arguments.
|
25
|
-
@params[param] = 1
|
26
|
-
end
|
29
|
+
# Flag params don't need to pass in arguments.
|
30
|
+
params[param] = args.any? ? args.join(',') : 1
|
27
31
|
self
|
28
32
|
end
|
29
33
|
end
|
@@ -32,16 +36,66 @@ module Cloudimage
|
|
32
36
|
alias_method from, to
|
33
37
|
end
|
34
38
|
|
35
|
-
def to_url(extra_params
|
36
|
-
|
37
|
-
|
39
|
+
def to_url(**extra_params)
|
40
|
+
set_uri_params(**extra_params)
|
41
|
+
secure_url
|
38
42
|
uri.to_s
|
39
43
|
end
|
40
44
|
|
41
45
|
private
|
42
46
|
|
43
|
-
def
|
44
|
-
|
47
|
+
def site
|
48
|
+
return "https://#{config[:cname]}" if config[:cname]
|
49
|
+
|
50
|
+
"https://#{config[:token]}.cloudimg.io"
|
51
|
+
end
|
52
|
+
|
53
|
+
def api_version
|
54
|
+
"/#{config[:api_version]}"
|
55
|
+
end
|
56
|
+
|
57
|
+
def transform(path)
|
58
|
+
path
|
59
|
+
.then { |input| input.start_with?('/') ? input : "/#{input}" }
|
60
|
+
.then(&method(:apply_aliases))
|
61
|
+
end
|
62
|
+
|
63
|
+
def apply_aliases(path)
|
64
|
+
return path if config[:aliases].empty?
|
65
|
+
|
66
|
+
path.dup.tap do |input|
|
67
|
+
config[:aliases].each do |source, target|
|
68
|
+
input.gsub!(source, target)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def request_uri
|
74
|
+
uri.request_uri.delete_prefix(api_version)
|
75
|
+
end
|
76
|
+
|
77
|
+
def build_uri
|
78
|
+
Addressable::URI.parse(site + api_version + path)
|
79
|
+
end
|
80
|
+
|
81
|
+
def set_uri_params(**extra_params)
|
82
|
+
seal_params(*extra_params.delete(:seal_params))
|
83
|
+
url_params = params.merge(**extra_params)
|
84
|
+
return unless url_params.any?
|
85
|
+
|
86
|
+
uri.query_values = url_params
|
87
|
+
end
|
88
|
+
|
89
|
+
def secure_url
|
90
|
+
return uri.to_s if config[:salt].nil?
|
91
|
+
|
92
|
+
security = Security.new(uri, **config)
|
93
|
+
|
94
|
+
if config[:sign_urls]
|
95
|
+
security.sign_url(request_uri)
|
96
|
+
else
|
97
|
+
security.seal_url(path, sealed_params)
|
98
|
+
end
|
45
99
|
end
|
46
100
|
end
|
47
101
|
end
|
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.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jan Klimo
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-08-02 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:
|
@@ -40,9 +68,11 @@ files:
|
|
40
68
|
- lib/cloudimage.rb
|
41
69
|
- lib/cloudimage/client.rb
|
42
70
|
- lib/cloudimage/custom_helpers.rb
|
71
|
+
- lib/cloudimage/invalidation.rb
|
43
72
|
- lib/cloudimage/params.rb
|
73
|
+
- lib/cloudimage/refinements.rb
|
74
|
+
- lib/cloudimage/security.rb
|
44
75
|
- lib/cloudimage/uri.rb
|
45
|
-
- lib/cloudimage/version.rb
|
46
76
|
homepage: https://github.com/scaleflex/cloudimage-rb
|
47
77
|
licenses:
|
48
78
|
- MIT
|
@@ -51,7 +81,7 @@ metadata:
|
|
51
81
|
changelog_uri: https://github.com/scaleflex/cloudimage-rb/blob/master/CHANGELOG.md
|
52
82
|
source_code_uri: https://github.com/scaleflex/cloudimage-rb
|
53
83
|
documentation_uri: https://docs.cloudimage.io/go/cloudimage-documentation-v7/en/introduction
|
54
|
-
post_install_message:
|
84
|
+
post_install_message:
|
55
85
|
rdoc_options: []
|
56
86
|
require_paths:
|
57
87
|
- lib
|
@@ -66,8 +96,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
66
96
|
- !ruby/object:Gem::Version
|
67
97
|
version: '0'
|
68
98
|
requirements: []
|
69
|
-
rubygems_version: 3.1.
|
70
|
-
signing_key:
|
99
|
+
rubygems_version: 3.1.4
|
100
|
+
signing_key:
|
71
101
|
specification_version: 4
|
72
102
|
summary: Official API wrapper for Cloudimage's API.
|
73
103
|
test_files: []
|