uploadcare-ruby 3.1.0 → 3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '08303dd0379957a7780c58d562c2ddbf9ae42e02d8069e19404defb9d7455292'
4
- data.tar.gz: d661a6c49bdcb5b5789b3e22dac0a0a439012f0a1bfc5a55b3cdc0c64094ef8b
3
+ metadata.gz: 43321c39c759dc538fc1df9c0383a7ed2c06bc94155202e861b65de39bfe18d1
4
+ data.tar.gz: 8b53ed1028a7fec8509be9d9b867c033f3dbb274b5235f4ef614cb879668e9b5
5
5
  SHA512:
6
- metadata.gz: b4b2c4f5342f48908731446e7ca2fa5aabef6568d99dede4ca46f3ed3df13993a156f70f84ac6a87d36799b2d589bc465814c7efeefcbfd6a3e459d3e378814f
7
- data.tar.gz: 0ffba57715c58eeeabc2d2b44884e67d09a5ee41b916fd10248e46822d5b35d3dd5c24c450ec4961a03b5a6f01903a5867007248bd347b88ac3568d89104c592
6
+ metadata.gz: a717971ee20ecf1b346303477d80fbf1c30e455a27d7fbb1bbc875f6037b64b924bc1ceb318e8b90bba7ef4a4ea9835ae801c878770933f42e2cfbb87c895251
7
+ data.tar.gz: cdb74b1395ddac124cbd49f7b3b9a268cf4badfbc84792d818dd3fc9193f24b6be41ba9349eaf4cf14804f73b632341c634e5a16e801f34aead70e3ee7784e1a
data/CHANGELOG.md CHANGED
@@ -1,31 +1,45 @@
1
1
  # Changelog
2
2
 
3
- ## 3.1.0 2021-09-21
3
+ ## 3.3.0 — 2022-04-08
4
4
 
5
- - Added documents and videos conversion
6
- - Added new attributes to the Entity class (variations, video_info, source, rekognition_info)
7
- - Added an opportunity to add custom logic to large files uploading process
5
+ - Added `Uploadcare::URLGenerators::AmakaiGenerator`. Use custom domain and CDN provider to deliver files with authenticated URLs.
8
6
 
9
- ## 3.0.5 2021-04-15
7
+ ## 3.2.0 2021-11-16
8
+
9
+ - Added option `signing_secret` to the `Uploadcare::Webhook`
10
+ - Added webhook signature verifier class `Uploadcare::Param::WebhookSignatureVerifier`
11
+
12
+ ## 3.1.1 — 2021-10-13
13
+
14
+ - Fixed `Uploadcare::File#store`
15
+ - Fixed `Uploadcare::File#delete`
16
+
17
+ ## 3.1.0 — 2021-09-21
18
+
19
+ - Added documents and videos conversions
20
+ - Added new attributes to the Entity class (`variations`, `video_info`, `source`, `rekognition_info`)
21
+ - Added an option to add custom logic to large files uploading process
22
+
23
+ ## 3.0.5 — 2021-04-15
10
24
 
11
25
  - Replace Travis-CI with Github Actions
12
26
  - Automate gem pushing
13
27
 
14
- ## 3.0.4-dev 2020-03-19
28
+ ## 3.0.4-dev 2020-03-19
15
29
 
16
- - Added better pagination methods for GroupList & FileList
30
+ - Added better pagination methods for `GroupList` & `FileList`
17
31
  - Improved documentation and install instructions
18
32
  - Added CI
19
33
 
20
- ## 3.0.3-dev 2020-03-13
21
- - Added better pagination and iterators for GroupList & FileList
34
+ ## 3.0.3-dev 2020-03-13
35
+ - Added better pagination and iterators for `GroupList` & `FileList`
22
36
 
23
- ## 3.0.2-dev 2020-03-11
37
+ ## 3.0.2-dev 2020-03-11
24
38
 
25
- - Expanded File and Group entities
39
+ - Expanded `File` and `Group` entities
26
40
  - Changed user agent syntax
27
41
 
28
- ## 3.0.1-dev 2020-03-11
42
+ ## 3.0.1-dev 2020-03-11
29
43
 
30
44
  - Added Upload/group functionality
31
45
  - Added user API
@@ -33,7 +47,7 @@
33
47
  - Isolated clients, entities and concerns
34
48
  - Expanded documentation
35
49
 
36
- ## 3.0.0-dev 2020-02-18
50
+ ## 3.0.0-dev 2020-02-18
37
51
 
38
52
  ### Changed
39
53
  - Rewrote gem from scratch
data/README.md CHANGED
@@ -52,7 +52,7 @@ And then execute:
52
52
 
53
53
  $ bundle
54
54
 
55
- If already not, create your project in [Uploadcare dashboard](https://uploadcare.com/dashboard/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby) and copy
55
+ If already not, create your project in [Uploadcare dashboard](https://app.uploadcare.com/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby) and copy
56
56
  its API keys from there.
57
57
 
58
58
  Set your Uploadcare keys in config file or through environment variables:
@@ -75,7 +75,10 @@ Uploadcare.config.secret_key = "demoprivatekey"
75
75
 
76
76
  This section contains practical usage examples. Please note, everything that
77
77
  follows gets way more clear once you've looked through our
78
- [docs](https://uploadcare.com/docs/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby).
78
+ [docs](https://uploadcare.com/docs/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby)
79
+ and [Upload](https://uploadcare.com/api-refs/upload-api/) and [REST](https://uploadcare.com/api-refs/rest-api/) API refs.
80
+
81
+ You can also find an example project [here](https://github.com/uploadcare/uploadcare-rails-example).
79
82
 
80
83
  ### Uploading files
81
84
  #### Uploading and storing a single file
@@ -91,7 +94,7 @@ Using Uploadcare is simple, and here are the basics of handling files.
91
94
  # => "dc99200d-9bd6-4b43-bfa9-aa7bfaefca40"
92
95
 
93
96
  # URL for the file, can be used with your website or app right away
94
- @uc_file.cdn_url
97
+ @uc_file.url
95
98
  # => "https://ucarecdn.com/dc99200d-9bd6-4b43-bfa9-aa7bfaefca40/"
96
99
  ```
97
100
 
@@ -116,6 +119,8 @@ Uploadcare supports multiple ways to upload files:
116
119
 
117
120
  ```ruby
118
121
  # Smart upload - detects type of passed object and picks appropriate upload method
122
+ # If you have a large file (more than 100Mb / 10485760 bytes), the uploader will automatically process it with a multipart upload
123
+
119
124
  Uploadcare::Uploader.upload("https://placekitten.com/96/139")
120
125
  ```
121
126
 
@@ -184,11 +189,6 @@ You can override global [`:autostore`](#initialization) option for each upload r
184
189
  ```
185
190
 
186
191
  ### File management
187
- Most methods are also available through `Uploadcare::Api` object:
188
- ```ruby
189
- # Same as Uploadcare::Uploader.upload
190
- Uploadcare::Api.upload("https://placekitten.com/96/139")
191
- ```
192
192
 
193
193
  Entities are representations of objects in Uploadcare cloud.
194
194
 
@@ -273,13 +273,13 @@ Metadata of deleted files is stored permanently.
273
273
 
274
274
  #### FileList
275
275
 
276
- `Uploadcare::Entity::FileList` represents the whole collection of files (or it's
276
+ `Uploadcare::FileList` represents the whole collection of files (or it's
277
277
  subset) and provides a way to iterate through it, making pagination transparent.
278
- FileList objects can be created using `Uploadcare::Entity.file_list` method.
278
+ FileList objects can be created using `Uploadcare::FileList.file_list` method.
279
279
 
280
280
  ```ruby
281
- @list = Uploadcare::Entity.file_list
282
- # Returns instance of Uploadcare::Api::FileList
281
+ @list = Uploadcare::FileList.file_list
282
+ # Returns instance of Uploadcare::Entity::FileList
283
283
  <Hashie::Mash
284
284
  next=nil
285
285
  per_page=100
@@ -294,14 +294,14 @@ FileList objects can be created using `Uploadcare::Entity.file_list` method.
294
294
  @all_files = @list.load
295
295
  ```
296
296
 
297
- This method accepts some options to controll which files should be fetched and
297
+ This method accepts some options to control which files should be fetched and
298
298
  how they should be fetched:
299
299
 
300
300
  - **:limit** — Controls page size. Accepts values from 1 to 1000, defaults to 100.
301
301
  - **:stored** — Can be either `true` or `false`. When true, file list will contain only stored files. When false — only not stored.
302
302
  - **:removed** — Can be either `true` or `false`. When true, file list will contain only removed files. When false — all except removed. Defaults to false.
303
- - **:ordering** — Controls the order of returned files. Available values: `datetime_updated`, `-datetime_updated`, `size`, `-size`. Defaults to `datetime_uploaded`. More info can be found [here](https://uploadcare.com/documentation/rest/#file-files/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby).
304
- - **:from** — Specifies the starting point for a collection. Resulting collection will contain files from the given value and to the end in a direction set by an **ordering** option. When files are ordered by `datetime_updated` in any direction, accepts either a `DateTime` object or an ISO 8601 string. When files are ordered by size, accepts non-negative integers (size in bytes). More info can be found [here](https://uploadcare.com/documentation/rest/#file-files/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby).
303
+ - **:ordering** — Controls the order of returned files. Available values: `datetime_updated`, `-datetime_updated`, `size`, `-size`. Defaults to `datetime_uploaded`. More info can be found [here](https://uploadcare.com/api-refs/rest-api/v0.6.0/#operation/filesList).
304
+ - **:from** — Specifies the starting point for a collection. Resulting collection will contain files from the given value and to the end in a direction set by an **ordering** option. When files are ordered by `datetime_updated` in any direction, accepts either a `DateTime` object or an ISO 8601 string. When files are ordered by size, accepts non-negative integers (size in bytes). More info can be found [here](https://uploadcare.com/api-refs/rest-api/v0.6.0/#operation/filesList).
305
305
 
306
306
  Options used to create a file list can be accessed through `#options` method.
307
307
  Note that, once set, they don't affect file fetching process anymore and are
@@ -326,11 +326,11 @@ To simply get all associated objects:
326
326
 
327
327
  Initially, `FileList` is a paginated collection. It can be navigated using following methods:
328
328
  ```ruby
329
- @file_list = Uploadcare::Entity::FileList.file_list
329
+ @file_list = Uploadcare::FileList.file_list
330
330
  # Let's assume there are 250 files in cloud. By default, UC loads 100 files. To get next 100 files, do:
331
331
  @next_page = @file_list.next_page
332
332
  # To get previous page:
333
- @previous_page = @next_page.previous_page
333
+ @previous_page = @file_list.previous_page
334
334
  ```
335
335
 
336
336
  Alternatively, it's possible to iterate through full list of groups or files with `each`:
@@ -351,7 +351,6 @@ That's a requirement of our API.
351
351
  @file = "134dc30c-093e-4f48-a5b9-966fe9cb1d01"
352
352
  @file2 = "134dc30c-093e-4f48-a5b9-966fe9cb1d02"
353
353
  @files_ary = [@file, @file2]
354
- @files = Uploadcare::Uploader.upload @files_ary
355
354
  @group = Uploadcare::Group.create @files
356
355
 
357
356
  # group can be stored by group ID. It means that all files of a group will be stored on Uploadcare servers permanently
@@ -375,18 +374,67 @@ https://uploadcare.com/docs/api_reference/rest/webhooks/
375
374
  You can use webhooks to provide notifications about your uploads to target urls.
376
375
  This gem lets you create and manage webhooks.
377
376
 
377
+ Each webhook payload can be signed with a secret (the `signing_secret` option) to ensure that the request comes from the expected sender.
378
+ More info about secure webhooks [here](https://uploadcare.com/docs/security/secure-webhooks/).
379
+
378
380
  ```ruby
379
- Uploadcare::Webhook.create(target_url: "https://example.com/listen", event: "file.uploaded", is_active: true)
380
- Uploadcare::Webhook.update(<webhook_id>, target_url: "https://newexample.com/listen/new", event: "file.uploaded", is_active: true)
381
+ Uploadcare::Webhook.create(target_url: "https://example.com/listen", event: "file.uploaded", is_active: true, signing_secret: "some-secret")
382
+ Uploadcare::Webhook.update(<webhook_id>, target_url: "https://newexample.com/listen/new", event: "file.uploaded", is_active: true, signing_secret: "some-secret")
381
383
  Uploadcare::Webhook.delete("https://example.com/listen")
382
384
  Uploadcare::Webhook.list
383
385
  ```
384
386
 
387
+ ##### Webhook signature verification
388
+
389
+ The gem has a helper class to verify a webhook signature from headers —
390
+ `Uploadcare::Param::WebhookSignatureVerifier`. This class accepts three
391
+ important options:
392
+
393
+ - **:webhook_body** — this option represents parameters received in the webhook
394
+ request in the JSON format.
395
+ **NOTE**: if you're using Rails, you should exclude options `controller`,
396
+ `action` and `post` from the `webhook_body`.
397
+ - **:signing_secret** — the secret that was set while creating/updating a
398
+ webhook. This option can be specified as an ENV var with the name
399
+ `UC_SIGNING_SECRET` — then no need to send it to the verifier class.
400
+ - **:x_uc_signature_header** — the content of the `X-Uc-Signature` HTTP header
401
+ in the webhook request.
402
+
403
+ Using the `Uploadcare::Param::WebhookSignatureVerifier` class example:
404
+
405
+ ```ruby
406
+ webhook_body = '{...}'
407
+
408
+ signing_secret = "12345X"
409
+ x_uc_signature_header = "v1=9b31c7dd83fdbf4a2e12b19d7f2b9d87d547672a325b9492457292db4f513c70"
410
+
411
+ Uploadcare::Param::WebhookSignatureVerifier.valid?(signing_secret: signing_secret, x_uc_signature_header: x_uc_signature_header, webhook_body: webhook_body)
412
+ ```
413
+
414
+ You can write your verifier. Example code:
415
+
416
+ ```ruby
417
+ webhook_body_json = '{...}'
418
+
419
+ signing_secret = ENV['UC_SIGNING_SECRET']
420
+ x_uc_signature_header = "v1=f4d859ed2fe47b9a4fcc81693d34e58ad12366a841e58a7072c1530483689cc0"
421
+
422
+ digest = OpenSSL::Digest.new('sha256')
423
+
424
+ calculated_signature = "v1=#{OpenSSL::HMAC.hexdigest(digest, signing_secret.force_encoding("utf-8"), webhook_body_json.force_encoding("utf-8"))}"
425
+
426
+ if calculated_signature == x_uc_signature_header
427
+ puts "WebHook signature matches!"
428
+ else
429
+ puts "WebHook signature mismatch!"
430
+ end
431
+ ```
432
+
385
433
  #### Project
386
434
 
387
435
  `Project` provides basic info about the connected Uploadcare project. That
388
436
  object is also an Hashie::Mash, so every methods out of
389
- [these](https://uploadcare.com/documentation/rest/#project/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby) will work.
437
+ [these](https://uploadcare.com/api-refs/rest-api/v0.6.0/#operation/projectInfo) will work.
390
438
 
391
439
  ```ruby
392
440
  @project = Uploadcare::Project.project
@@ -405,8 +453,6 @@ object is also an Hashie::Mash, so every methods out of
405
453
 
406
454
  ##### Video
407
455
 
408
- Uploadcare can encode video files from all popular formats, adjust their quality, format and dimensions, cut out a video fragment, and generate thumbnails via [REST API](https://uploadcare.com/api-refs/rest-api/v0.6.0/).
409
-
410
456
  After each video file upload you obtain a file identifier in UUID format.
411
457
  Then you can use this file identifier to convert your video in multiple ways:
412
458
 
@@ -467,7 +513,7 @@ Params in the response:
467
513
  - **original_source** - built path for a particular video with all the conversion operations and parameters.
468
514
  - **token** - a processing job token that can be used to get a [job status](https://uploadcare.com/docs/transformations/video-encoding/#status) (see below).
469
515
  - **uuid** - UUID of your processed video file.
470
- - **thumbnails_group_uuid** - holds :uuid-thumb-group, a UUID of a [file group](https://uploadcare.com/api-refs/rest-api/v0.5.0/#operation/groupsList) with thumbnails for an output video, based on the thumbs [operation](https://uploadcare.com/docs/transformations/video-encoding/#operation-thumbs) parameters.
516
+ - **thumbnails_group_uuid** - holds :uuid-thumb-group, a UUID of a [file group](https://uploadcare.com/api-refs/rest-api/v0.6.0/#operation/groupsList) with thumbnails for an output video, based on the thumbs [operation](https://uploadcare.com/docs/transformations/video-encoding/#operation-thumbs) parameters.
471
517
  - **problems** - problems related to your processing job, if any.
472
518
 
473
519
  To convert multiple videos just add params as a hash for each video to the first argument of the `Uploadcare::VideoConverter#convert` method:
@@ -514,12 +560,10 @@ Params in the response:
514
560
  - **thumbnails_group_uuid** - holds :uuid-thumb-group, a UUID of a file group with thumbnails for an output video, based on the thumbs operation parameters.
515
561
  - **uuid** - a UUID of your processed video file.
516
562
 
517
- More examples and options can be found [here](https://uploadcare.com/docs/transformations/video-encoding/#video-encoding)
563
+ More examples and options can be found [here](https://uploadcare.com/docs/transformations/video-encoding/#video-encoding).
518
564
 
519
565
  ##### Document
520
566
 
521
- Uploadcare allows converting documents to the following target formats: doc, docx, xls, xlsx, odt, ods, rtf, txt, pdf, jpg, png. Document Conversion works via our [REST API](https://uploadcare.com/api-refs/rest-api/v0.6.0/).
522
-
523
567
  After each document file upload you obtain a file identifier in UUID format.
524
568
  Then you can use this file identifier to convert your document to a new format:
525
569
 
@@ -617,13 +661,27 @@ Params in the response:
617
661
 
618
662
  More examples and options can be found [here](https://uploadcare.com/docs/transformations/document-conversion/#document-conversion)
619
663
 
664
+ ## Secure delivery
665
+
666
+ You can use custom domain and CDN provider to deliver files with authenticated URLs (see [original documentation](https://uploadcare.com/docs/security/secure_delivery/)).
667
+
668
+ To generate authenticated URL from the library, you should choose `Uploadcare::URLGenerators::AmakaiGenerator` (or create your generator implementation):
669
+ ```ruby
670
+ generator = Uploadcare::URLGenerators::AmakaiGenerator.new(cdn_host: 'example.com', secret_key: 'secret_key'). Optional parameters: ttl: 300, algorithm: 'sha256'
671
+ generator.generate_url(uuid, acl: optional)
672
+
673
+ generator.generate_url("a7d5645e-5cd7-4046-819f-a6a2933bafe3") ->
674
+ https://example.com/a7d5645e-5cd7-4046-819f-a6a2933bafe3/?token=exp=1649405263~acl=/a7d5645e-5cd7-4046-819f-a6a2933bafe3/~hmac=a989cae5342f17013677f5a0e6577fc5594cc4e238fb4c95eda36634eb47018b
675
+ generator.generate_url("a7d5645e-5cd7-4046-819f-a6a2933bafe3", '/*/') ->
676
+ https://example.com/a7d5645e-5cd7-4046-819f-a6a2933bafe3/?token=exp=1649405263~acl=/*/~hmac=3ce1152c6af8864b36d4dc721f08ca3cf0b3a20278d7f849e82c6c930d48ccc1
677
+ ```
620
678
  ## Useful links
621
679
 
622
680
  * [Development](https://github.com/uploadcare/uploadcare-ruby/blob/main/DEVELOPMENT.md)
623
- * [Uploadcare documentation](https://uploadcare.com/docs/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby)
624
- * [Upload API reference](https://uploadcare.com/api-refs/upload-api/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby)
625
- * [REST API reference](https://uploadcare.com/api-refs/rest-api/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby)
626
- * [Changelog](./CHANGELOG.md)
627
- * [Contributing guide](https://github.com/uploadcare/.github/blob/master/CONTRIBUTING.md)
628
- * [Security policy](https://github.com/uploadcare/uploadcare-ruby/security/policy)
629
- * [Support](https://github.com/uploadcare/.github/blob/master/SUPPORT.md)
681
+ * [Uploadcare documentation](https://uploadcare.com/docs/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby)
682
+ * [Upload API reference](https://uploadcare.com/api-refs/upload-api/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby)
683
+ * [REST API reference](https://uploadcare.com/api-refs/rest-api/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby)
684
+ * [Changelog](./CHANGELOG.md)
685
+ * [Contributing guide](https://github.com/uploadcare/.github/blob/master/CONTRIBUTING.md)
686
+ * [Security policy](https://github.com/uploadcare/uploadcare-ruby/security/policy)
687
+ * [Support](https://github.com/uploadcare/.github/blob/master/SUPPORT.md)
@@ -1,12 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'rest_client'
4
+
3
5
  module Uploadcare
4
6
  module Client
5
7
  # API client for getting project info
6
8
  # @see https://uploadcare.com/docs/api_reference/rest/handling_projects/
7
9
  class ProjectClient < RestClient
8
10
  # get information about current project
9
- # current project is determined by public and private key combination
11
+ # current project is determined by public and secret key combination
10
12
  # @see https://uploadcare.com/api-refs/rest-api/v0.5.0/#tag/Project
11
13
  def show
12
14
  get(uri: '/project/')
@@ -14,7 +14,9 @@ module Uploadcare
14
14
  'target_url': options[:target_url],
15
15
  'event': options[:event] || 'file.uploaded',
16
16
  'is_active': options[:is_active].nil? ? true : options[:is_active]
17
- }.to_json
17
+ }.merge(
18
+ { 'signing_secret': options[:signing_secret] }.compact
19
+ ).to_json
18
20
  post(uri: '/webhooks/', content: body)
19
21
  end
20
22
 
@@ -44,7 +44,7 @@ module Uploadcare
44
44
  #
45
45
  # It's possible to avoid loading objects on previous pages by offsetting them first
46
46
  def load
47
- return if @entity[:next].nil? || @entity[:results].length == @entity[:total]
47
+ return self if @entity[:next].nil? || @entity[:results].length == @entity[:total]
48
48
 
49
49
  np = self
50
50
  until np.next.nil?
@@ -91,6 +91,17 @@ module Uploadcare
91
91
  File.copy(uuid, target: target, **args)
92
92
  end
93
93
 
94
+ # Store a single file, preventing it from being deleted in 2 weeks
95
+ # @see https://uploadcare.com/api-refs/rest-api/v0.5.0/#operation/storeFile
96
+ def store
97
+ File.store(uuid)
98
+ end
99
+
100
+ # @see https://uploadcare.com/api-refs/rest-api/v0.5.0/#operation/deleteFile
101
+ def delete
102
+ File.delete(uuid)
103
+ end
104
+
94
105
  private
95
106
 
96
107
  def convert_file(params, converter, options = {})
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'digest/md5'
4
+
5
+ module Uploadcare
6
+ module Param
7
+ # This object verifies a signature received along with webhook headers
8
+ class WebhookSignatureVerifier
9
+ # @see https://uploadcare.com/docs/security/secure-webhooks/
10
+ def self.valid?(options = {})
11
+ webhook_body_json = options[:webhook_body]
12
+ signing_secret = options[:signing_secret] || ENV['UC_SIGNING_SECRET']
13
+ x_uc_signature_header = options[:x_uc_signature_header]
14
+
15
+ digest = OpenSSL::Digest.new('sha256')
16
+
17
+ calculated_signature = "v1=#{OpenSSL::HMAC.hexdigest(digest, signing_secret, webhook_body_json)}"
18
+
19
+ calculated_signature == x_uc_signature_header
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Uploadcare
4
- VERSION = '3.1.0'
4
+ VERSION = '3.3.0'
5
5
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_generator'
4
+
5
+ module Uploadcare
6
+ module SignedUrlGenerators
7
+ class AmakaiGenerator < Uploadcare::SignedUrlGenerators::BaseGenerator
8
+ UUID_REGEX = '[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}'
9
+ TEMPLATE = 'https://{cdn_host}/{uuid}/?token=exp={expiration}{delimiter}acl={acl}{delimiter}hmac={token}'
10
+
11
+ def generate_url(uuid, acl = uuid)
12
+ raise ArgumentError, 'Must contain valid UUID' unless valid?(uuid)
13
+
14
+ expire = build_expire
15
+ signature = build_signature(expire, acl)
16
+
17
+ TEMPLATE.gsub('{delimiter}', delimiter)
18
+ .sub('{cdn_host}', sanitized_string(cdn_host))
19
+ .sub('{uuid}', sanitized_string(uuid))
20
+ .sub('{acl}', "/#{sanitized_string(acl)}/")
21
+ .sub('{expiration}', expire)
22
+ .sub('{token}', signature)
23
+ end
24
+
25
+ private
26
+
27
+ def valid?(uuid)
28
+ uuid.match(UUID_REGEX)
29
+ end
30
+
31
+ def delimiter
32
+ '~'
33
+ end
34
+
35
+ def build_expire
36
+ (Time.now.to_i + ttl).to_s
37
+ end
38
+
39
+ def build_signature(expire, acl)
40
+ signature = ["exp=#{expire}", "acl=/#{sanitized_string(acl)}/"].join(delimiter)
41
+ OpenSSL::HMAC.hexdigest(algorithm, secret_key, signature)
42
+ end
43
+
44
+ # rubocop:disable Style/SlicingWithRange
45
+ def sanitized_string(string)
46
+ string = string[1..-1] if string[0] == '/'
47
+ string = string[0...-1] if string[-1] == '/'
48
+ string.strip
49
+ end
50
+ # rubocop:enable Style/SlicingWithRange
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Uploadcare
4
+ module SignedUrlGenerators
5
+ class BaseGenerator
6
+ attr_accessor :cdn_host, :ttl, :algorithm
7
+ attr_reader :secret_key
8
+
9
+ def initialize(cdn_host:, secret_key:, ttl: 300, algorithm: 'sha256')
10
+ @ttl = ttl
11
+ @algorithm = algorithm
12
+ @cdn_host = cdn_host
13
+ @secret_key = secret_key
14
+ end
15
+
16
+ def generate_url
17
+ raise NotImplementedError, "#{__method__} method not present"
18
+ end
19
+ end
20
+ end
21
+ end
data/lib/uploadcare.rb CHANGED
@@ -17,6 +17,9 @@ require 'entity/project'
17
17
  require 'entity/uploader'
18
18
  require 'entity/webhook'
19
19
 
20
+ # Param
21
+ require 'param/webhook_signature_verifier'
22
+
20
23
  # General api
21
24
  require 'api/api'
22
25
 
@@ -38,7 +38,7 @@ Gem::Specification.new do |spec|
38
38
  spec.require_paths = ['lib', 'lib/uploadcare', 'lib/uploadcare/rest']
39
39
 
40
40
  spec.add_dependency 'api_struct', '~> 1.0.1'
41
- spec.add_dependency 'dry-configurable', '~> 0.9.0'
41
+ spec.add_dependency 'dry-configurable', '~> 0.9'
42
42
  spec.add_dependency 'parallel'
43
43
  spec.add_dependency 'retries'
44
44
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uploadcare-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 3.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stepan Redka
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-09-21 00:00:00.000000000 Z
11
+ date: 2022-04-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: api_struct
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.9.0
33
+ version: '0.9'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.9.0
40
+ version: '0.9'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: parallel
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -214,7 +214,10 @@ files:
214
214
  - lib/uploadcare/param/upload/signature_generator.rb
215
215
  - lib/uploadcare/param/upload/upload_params_generator.rb
216
216
  - lib/uploadcare/param/user_agent.rb
217
+ - lib/uploadcare/param/webhook_signature_verifier.rb
217
218
  - lib/uploadcare/ruby/version.rb
219
+ - lib/uploadcare/signed_url_generators/amakai_generator.rb
220
+ - lib/uploadcare/signed_url_generators/base_generator.rb
218
221
  - uploadcare-ruby.gemspec
219
222
  homepage: https://github.com/uploadcare/uploadcare-ruby
220
223
  licenses: