cloudimage 0.1.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
![](https://github.com/scaleflex/cloudimage-rb/workflows/Build/badge.svg)
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/cloudimage.svg)](https://badge.fury.io/rb/cloudimage) ![Build status](https://github.com/scaleflex/cloudimage-rb/workflows/Build/badge.svg)
|
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
|
![token](docs/token.png)
|
@@ -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: []
|