shrine-aws-lambda 0.1.2 → 0.2.1
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 -9
- data/README.md +75 -61
- data/lib/shrine/plugins/aws_lambda/version.rb +1 -1
- data/lib/shrine/plugins/aws_lambda.rb +35 -16
- data/shrine-aws-lambda.gemspec +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 171dc0f2dc4d0e578d3318fbe784c9ea3f7b54ce44492ff957c18aa6ffc302c7
|
|
4
|
+
data.tar.gz: fb725564eb46f01f5f3c226d7cd216798ce64afed2ff4c2720e2b9f977c7ea06
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bdf72fb943347acecf82e462b0fdca2b1767b58d060ad18f769565e72e59b7bbbf2700900ab187b3ac6297c15320ac3486013567e9986da77fe0869076332009
|
|
7
|
+
data.tar.gz: 0105132b06a275f116045c7f371aaeec54b5e2f29cb583d3ac03fa01a6f0540022e1fd67b70b0e5021f429f0278cde496ac2ed1fe0e2301e9b808dacc56b4263
|
data/CHANGELOG.md
CHANGED
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [v0.1
|
|
3
|
+
## [v0.2.1](https://github.com/texpert/shrine-aws-lambda/tree/v0.2.1) (2023-05-15)
|
|
4
4
|
|
|
5
|
-
[Full Changelog](https://github.com/texpert/shrine-aws-lambda/compare/
|
|
5
|
+
[Full Changelog](https://github.com/texpert/shrine-aws-lambda/compare/v0.2.0...v0.2.1)
|
|
6
6
|
|
|
7
7
|
**Merged pull requests:**
|
|
8
8
|
|
|
9
|
-
-
|
|
9
|
+
- Fix generate\_location method call to be Shrine 3.x and Ruby 3.x compliant [\#5](https://github.com/texpert/shrine-aws-lambda/pull/5) ([texpert](https://github.com/texpert))
|
|
10
|
+
- Bump asdf Ruby to 2.7.8, use bundler 2.3.26 [\#4](https://github.com/texpert/shrine-aws-lambda/pull/4) ([texpert](https://github.com/texpert))
|
|
10
11
|
|
|
11
|
-
##
|
|
12
|
+
## [v0.2.0](https://github.com/texpert/shrine-aws-lambda/tree/v0.2.0) (2022-08-27)
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
- **Breaking:** Change class name from Shrine::Plugins::Lambda to Shrine::Plugins::AwsLambda
|
|
15
|
-
- **Breaking:** Change plugin registration symbol from `:lambda` to `:aws_lambda`
|
|
14
|
+
[Full Changelog](https://github.com/texpert/shrine-aws-lambda/compare/v0.1.2...v0.2.0)
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
**Merged pull requests:**
|
|
17
|
+
|
|
18
|
+
- Upgrade to work with Shrine version 3 [\#3](https://github.com/texpert/shrine-aws-lambda/pull/3) ([texpert](https://github.com/texpert))
|
|
19
|
+
|
|
20
|
+
## [v0.1.2](https://github.com/texpert/shrine-aws-lambda/tree/v0.1.2) (2022-07-03)
|
|
21
|
+
|
|
22
|
+
[Full Changelog](https://github.com/texpert/shrine-aws-lambda/compare/88f53efc0436de444f438d36b8a831b4013f5778...v0.1.2)
|
|
23
|
+
|
|
24
|
+
**Merged pull requests:**
|
|
25
|
+
|
|
26
|
+
- Initial, compatible with shrine-lambda, release [\#1](https://github.com/texpert/shrine-aws-lambda/pull/1) ([texpert](https://github.com/texpert))
|
|
19
27
|
|
|
20
28
|
|
|
21
29
|
|
data/README.md
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
# Shrine::Plugins::AwsLambda
|
|
2
|
-
Provides [AWS Lambda] integration for [Shrine] File Attachment toolkit for Ruby applications
|
|
2
|
+
Provides [AWS Lambda] integration for the [Shrine] File Attachment toolkit for Ruby applications
|
|
3
3
|
|
|
4
|
-
This is a gem, renamed from initial [shrine-lambda](https://github.com/texpert/shrine-lambda) to [shrine-aws-lambda](https://github.com/texpert/shrine-aws-lambda)
|
|
5
|
-
for clarity
|
|
4
|
+
This is a gem, renamed from the initial [shrine-lambda](https://github.com/texpert/shrine-lambda) to [shrine-aws-lambda](https://github.com/texpert/shrine-aws-lambda) for clarity
|
|
6
5
|
|
|
7
6
|
## Description
|
|
8
7
|
|
|
@@ -53,7 +52,7 @@ either in the [Shrine] initializer, or in [default profile][AWS profiles] in the
|
|
|
53
52
|
region: 'your AWS bucket region' }
|
|
54
53
|
```
|
|
55
54
|
|
|
56
|
-
Also, for
|
|
55
|
+
Also, for Lambda functions to work, various [AWS Lambda permissions] should be managed on the [Amazon Web Services] side.
|
|
57
56
|
|
|
58
57
|
Add to the [Shrine]'s initializer file the Shrine-AWS-Lambda plugin registration with the `:callback_url` parameter,
|
|
59
58
|
and the [AWS Lambda] functions list retrieval call (which will retrieve the functions list on application initialization
|
|
@@ -71,11 +70,11 @@ and will store the list into the `Shrine.opts[:lambda_function_list]` for furthe
|
|
|
71
70
|
By default, Shrine-AWS-Lambda is using the S3 bucket named `:cache` for retrieving the original file, and the `:store`
|
|
72
71
|
named S3 bucket for storing the resulting files.
|
|
73
72
|
|
|
74
|
-
|
|
75
|
-
into the Shrine's initializer.
|
|
73
|
+
Shrine-AWS-Lambda uses the [Shrine backgrounding plugin] for asynchronous operation, so this plugin should be also
|
|
74
|
+
included into the Shrine's initializer.
|
|
76
75
|
|
|
77
|
-
Here is a full example of a Shrine initializer of a [Rails] application using [Roda]
|
|
78
|
-
(used for direct file uploads to [AWS S3]) and [AWS Lambda] callbacks:
|
|
76
|
+
Here is a full example of a Shrine initializer of a [Rails] application using a [Roda] endpoint for presigned_url
|
|
77
|
+
(used for direct file uploads to [AWS S3]) and [AWS Lambda] callbacks):
|
|
79
78
|
|
|
80
79
|
```ruby
|
|
81
80
|
# config/initializers/shrine.rb:
|
|
@@ -94,72 +93,78 @@ if Rails.env.test?
|
|
|
94
93
|
else
|
|
95
94
|
require 'shrine/storage/s3'
|
|
96
95
|
|
|
97
|
-
|
|
96
|
+
aws_credentials = Rails.application.credentials.aws
|
|
98
97
|
|
|
99
|
-
s3_options = { access_key_id:
|
|
100
|
-
secret_access_key:
|
|
98
|
+
s3_options = { access_key_id: aws_credentials[:access_key_id],
|
|
99
|
+
secret_access_key: aws_credentials[:secret_access_key],
|
|
101
100
|
region: 'us-east-2' }
|
|
102
101
|
|
|
103
102
|
if Rails.env.production?
|
|
104
|
-
cache_bucket = store_bucket =
|
|
103
|
+
cache_bucket = store_bucket = aws_credentials.aws_s3_bucket
|
|
105
104
|
else
|
|
106
105
|
cache_bucket = 'texpert-test-cache'
|
|
107
106
|
store_bucket = 'texpert-test-store'
|
|
108
107
|
end
|
|
109
108
|
|
|
110
|
-
Shrine.storages = {
|
|
111
|
-
|
|
112
|
-
store: Shrine::Storage::S3.new(prefix: 'store', **s3_options.merge(bucket: store_bucket))
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
lambda_callback_url = if Rails.env.development?
|
|
116
|
-
"http://#{ENV['USER']}.localtunnel.me/rapi/lambda"
|
|
117
|
-
else
|
|
118
|
-
"https://#{ENV.fetch('APP_HOST')}/rapi/lambda"
|
|
119
|
-
end
|
|
109
|
+
Shrine.storages = { cache: Shrine::Storage::S3.new(prefix: 'cache', **s3_options.merge!(bucket: cache_bucket)),
|
|
110
|
+
store: Shrine::Storage::S3.new(prefix: 'store', **s3_options.merge!(bucket: store_bucket)) }
|
|
120
111
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
content_type = Rack::Mime.mime_type(extension)
|
|
112
|
+
ActiveSupport::Reloader.to_prepare do
|
|
113
|
+
lambda_callback_url = if Rails.env.development? && NGROK_ENABLED
|
|
114
|
+
"#{NGROK_URL}/rapi/lambda"
|
|
115
|
+
else
|
|
116
|
+
"https://#{ENV['APP_HOST'] || 'localhost'}/rapi/lambda"
|
|
117
|
+
end
|
|
128
118
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
content_disposition: "attachment; filename=\"#{filename}\"", # download with original filename
|
|
132
|
-
content_type: content_type, # set correct content type
|
|
133
|
-
}
|
|
119
|
+
Shrine.plugin :aws_lambda, s3_options.merge!(callback_url: lambda_callback_url)
|
|
120
|
+
Shrine.lambda_function_list
|
|
134
121
|
end
|
|
135
122
|
end
|
|
136
123
|
|
|
137
124
|
Shrine.plugin :activerecord
|
|
138
125
|
Shrine.plugin :backgrounding
|
|
139
126
|
Shrine.plugin :cached_attachment_data # for forms
|
|
140
|
-
|
|
127
|
+
|
|
128
|
+
Shrine.logger = Rails.logger
|
|
129
|
+
Shrine.plugin :instrumentation
|
|
130
|
+
|
|
131
|
+
Shrine.plugin :presign_endpoint, presign_options: lambda { |request|
|
|
132
|
+
filename = request.params['filename']
|
|
133
|
+
extension = File.extname(filename)
|
|
134
|
+
content_type = Rack::Mime.mime_type(extension)
|
|
135
|
+
|
|
136
|
+
{ content_length_range: 0..1.gigabyte, # limit filesize to 1 GB
|
|
137
|
+
content_disposition: "attachment; filename=\"#{filename}\"", # download with original filename
|
|
138
|
+
content_type: content_type } # set correct content type
|
|
139
|
+
}
|
|
140
|
+
|
|
141
141
|
Shrine.plugin :rack_file # for non-Rails apps
|
|
142
142
|
Shrine.plugin :remote_url, max_size: 1.gigabyte
|
|
143
143
|
|
|
144
|
-
Shrine::Attacher.
|
|
145
|
-
Shrine::Attacher.
|
|
144
|
+
Shrine::Attacher.promote_block { PromoteJob.enqueue(self.class.name, record.class.name, record.id, name, file_data) }
|
|
145
|
+
Shrine::Attacher.destroy_block { DeleteJob.enqueue(self.class.name, data) }
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Take notice that the promote job is a default, not AWS Lambda job:
|
|
146
149
|
|
|
150
|
+
```
|
|
151
|
+
Shrine::Attacher.promote_block { PromoteJob.enqueue(self.class.name, record.class.name, record.id, name, file_data) }
|
|
147
152
|
```
|
|
148
153
|
|
|
149
|
-
Take notice that the promote job is a default `Shrine::Attacher.promote { |data| PromoteJob.perform_later(data) }`.
|
|
150
154
|
This is made to be able to use other than AWS storages in the test environment (like Shrine's `FileSystem` storage)
|
|
151
|
-
and, also, other uploaders which are not using [AWS Lambda].
|
|
152
|
-
directly in the uploaders' classes which will use [AWS Lambda]
|
|
155
|
+
and, also, other uploaders which are not using [AWS Lambda]. To use an AWS Lambda job, this job must be overridden
|
|
156
|
+
to a `LambdaPromoteJob` directly in the uploaders' classes which will use [AWS Lambda] - see below in the **Usage**
|
|
157
|
+
chapter.
|
|
153
158
|
|
|
154
|
-
Another thing used in this initializer is the [
|
|
159
|
+
Another thing used in this initializer is the [ngrok-wrapper] gem for exposing the localhost to the world for
|
|
155
160
|
catching the Lambda callback requests.
|
|
156
161
|
|
|
157
162
|
#### How it works
|
|
158
163
|
|
|
159
|
-
Shrine-
|
|
164
|
+
Shrine-AWS-Lambda works in such a way that an "assembly" should be created in the `LambdaUploader`, which contains all
|
|
160
165
|
the information about how the file should be processed. A random generated string is appended to the assembly, stored
|
|
161
166
|
into the cached file metadata, and used by the Lambda function to sign the requests to the `:lambda_callback_url`,
|
|
162
|
-
along with the `:access_key_id` from the
|
|
167
|
+
along with the AWS `:access_key_id` from the AWS credentials Lambda function is running with.
|
|
163
168
|
|
|
164
169
|
Processing itself happens asynchronously - the invoked Lambda function will issue a PUT HTTP request to the
|
|
165
170
|
`:lambda_callback_url`, specified in the Shrine's initializer, with the request's payload containing the processing
|
|
@@ -168,9 +173,9 @@ results.
|
|
|
168
173
|
The request should be intercepted by a endpoint at the `:lambda_callback_url`, and its payload transferred to the
|
|
169
174
|
`lambda_save` method on successful request authorization.
|
|
170
175
|
|
|
171
|
-
The authorization is
|
|
172
|
-
the Lambda function's `:access_key_id` received in the request authorization header. Then, the calculated
|
|
173
|
-
compared to the received in the same authorization header Lambda signature.
|
|
176
|
+
The authorization is calculating the HTTP request signature using the random string stored in the cached file and
|
|
177
|
+
the AWS Lambda function's `:access_key_id` received in the request authorization header. Then, the calculated
|
|
178
|
+
signature is compared to the received in the same authorization header AWS Lambda signature.
|
|
174
179
|
|
|
175
180
|
#### Usage
|
|
176
181
|
|
|
@@ -182,7 +187,11 @@ Shrine-AWS-Lambda assemblies are built inside the `#lambda_process_versions` met
|
|
|
182
187
|
# frozen_string_literal: true
|
|
183
188
|
|
|
184
189
|
class LambdaUploader < Uploader
|
|
185
|
-
|
|
190
|
+
unless Rails.env.test?
|
|
191
|
+
Attacher.promote_block do
|
|
192
|
+
LambdaPromoteJob.enqueue(self.class.name, record.class.name, record.id, name, file_data)
|
|
193
|
+
end
|
|
194
|
+
end
|
|
186
195
|
|
|
187
196
|
plugin :upload_options, store: ->(_io, context) do
|
|
188
197
|
if %i[avatar logo].include?(context[:name])
|
|
@@ -219,7 +228,6 @@ class LambdaUploader < Uploader
|
|
|
219
228
|
assembly
|
|
220
229
|
end
|
|
221
230
|
end
|
|
222
|
-
|
|
223
231
|
```
|
|
224
232
|
|
|
225
233
|
The above example is built to interact with the [lambda-image-resize] function, which is using the [Sharp] Javascript
|
|
@@ -240,14 +248,13 @@ The default options used by Shrine-AWS-Lambda plugin are the following:
|
|
|
240
248
|
target_storage: :store }
|
|
241
249
|
```
|
|
242
250
|
|
|
243
|
-
These options could be
|
|
251
|
+
These options could be overridden in the `LambdaUploader` specifying them as the `assembly` keys:
|
|
244
252
|
|
|
245
253
|
```ruby
|
|
246
|
-
assembly[:callbackURL] = some_callback_url
|
|
247
|
-
assembly[:copy_original
|
|
254
|
+
assembly[:callbackURL] = some_callback_url
|
|
255
|
+
assembly[:copy_original] = false # If this is `false`, only the processed file versions will be stored
|
|
248
256
|
assembly[:storages] = Shrine.buckets_to_use(%i[cache store other_store])
|
|
249
257
|
assembly[:target_storage] = :other_store
|
|
250
|
-
|
|
251
258
|
```
|
|
252
259
|
|
|
253
260
|
Any S3 buckets could be specified, as long as the buckets are defined in the Shrine's initializer file.
|
|
@@ -294,7 +301,6 @@ module RAPI
|
|
|
294
301
|
end
|
|
295
302
|
end
|
|
296
303
|
end
|
|
297
|
-
|
|
298
304
|
```
|
|
299
305
|
|
|
300
306
|
#### Backgrounding
|
|
@@ -302,7 +308,13 @@ end
|
|
|
302
308
|
Even though submitting a Lambda assembly doesn't require any uploading, it still does a HTTP request, so it is better
|
|
303
309
|
to put it into a background job. This is configured in the `LambdaUploader` class:
|
|
304
310
|
|
|
305
|
-
|
|
311
|
+
```ruby
|
|
312
|
+
unless Rails.env.test?
|
|
313
|
+
Attacher.promote_block do
|
|
314
|
+
LambdaPromoteJob.enqueue(self.class.name, record.class.name, record.id, name, file_data)
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
```
|
|
306
318
|
|
|
307
319
|
Then the job file should be implemented:
|
|
308
320
|
|
|
@@ -311,9 +323,11 @@ Then the job file should be implemented:
|
|
|
311
323
|
|
|
312
324
|
# frozen_string_literal: true
|
|
313
325
|
|
|
314
|
-
class LambdaPromoteJob <
|
|
315
|
-
def
|
|
316
|
-
|
|
326
|
+
class LambdaPromoteJob < Que::Job
|
|
327
|
+
def run(...)
|
|
328
|
+
ActiveRecord::Base.transaction do
|
|
329
|
+
Shrine::Attacher.lambda_process(...)
|
|
330
|
+
end
|
|
317
331
|
end
|
|
318
332
|
end
|
|
319
333
|
```
|
|
@@ -360,7 +374,7 @@ by the following command:
|
|
|
360
374
|
$ gem build shrine-aws-lambda.gemspec
|
|
361
375
|
```
|
|
362
376
|
|
|
363
|
-
Assuming the version was set to `0.
|
|
377
|
+
Assuming the version was set to `0.2.0`, a `shrine-aws-lambda-0.2.0.gem` binary file will be generated at the root of
|
|
364
378
|
the app (repo).
|
|
365
379
|
|
|
366
380
|
- The binary file shouldn't be added into the `git` tree, it will be pushed into the RubyGems and to the GitHub releases
|
|
@@ -368,7 +382,7 @@ the app (repo).
|
|
|
368
382
|
#### Pushing a new gem release to RubyGems
|
|
369
383
|
|
|
370
384
|
```bash
|
|
371
|
-
$ gem push shrine-aws-lambda-0.
|
|
385
|
+
$ gem push shrine-aws-lambda-0.2.0.gem # don't forget to specify the correct version number
|
|
372
386
|
```
|
|
373
387
|
|
|
374
388
|
#### Crafting the new release on GitHub
|
|
@@ -403,12 +417,12 @@ article], which pointed me to use the [Sharp] library for image resizing.
|
|
|
403
417
|
[Amazon Web Services]: https://aws.amazon.com
|
|
404
418
|
[AWS blog article]: https://aws.amazon.com/blogs/compute/resize-images-on-the-fly-with-amazon-s3-aws-lambda-and-amazon-api-gateway/
|
|
405
419
|
[AWS Lambda]: https://aws.amazon.com/lambda
|
|
406
|
-
[AWS
|
|
420
|
+
[AWS Lambda permissions]: https://docs.aws.amazon.com/lambda/latest/dg/intro-permission-model.html
|
|
407
421
|
[AWS profiles]: https://docs.aws.amazon.com/cli/latest/userguide/cli-multiple-profiles.html
|
|
408
422
|
[AWS S3]: https://aws.amazon.com/s3/
|
|
409
423
|
[Janko]: https://github.com/janko-m
|
|
410
424
|
[lambda-image-resize]: https://github.com/texpert/lambda-image-resize.js
|
|
411
|
-
[
|
|
425
|
+
[ngrok-wrapper]: https://github.com/texpert/ngrok-wrapper
|
|
412
426
|
[Rails]: http://rubyonrails.org
|
|
413
427
|
[Roda]: http://roda.jeremyevans.net
|
|
414
428
|
[Sharp]: https://github.com/lovell/sharp
|
|
@@ -59,9 +59,12 @@ class Shrine
|
|
|
59
59
|
module AttacherClassMethods
|
|
60
60
|
# Loads the attacher from the data, and triggers its instance AWS Lambda
|
|
61
61
|
# processing method. Intended to be used in a background job.
|
|
62
|
-
def lambda_process(
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
def lambda_process(attacher_class, record_class, record_id, name, file_data)
|
|
63
|
+
attacher_class = Object.const_get(attacher_class)
|
|
64
|
+
record = Object.const_get(record_class).find(record_id) # if using Active Record
|
|
65
|
+
|
|
66
|
+
attacher = attacher_class.retrieve(model: record, name: name, file: file_data)
|
|
67
|
+
attacher.lambda_process
|
|
65
68
|
attacher
|
|
66
69
|
end
|
|
67
70
|
|
|
@@ -85,12 +88,28 @@ class Shrine
|
|
|
85
88
|
# @return [false] if signature in received headers does't match locally computed AWS signature
|
|
86
89
|
def lambda_authorize(headers, body)
|
|
87
90
|
result = JSON.parse(body)
|
|
88
|
-
|
|
91
|
+
context = result['context']
|
|
92
|
+
|
|
93
|
+
context_record = context['record']
|
|
94
|
+
record_class = context_record[0]
|
|
95
|
+
record_id = context_record[1]
|
|
96
|
+
record = Object.const_get(record_class).find(record_id)
|
|
97
|
+
attacher_name = context['name']
|
|
98
|
+
attacher = record.__send__(:"#{attacher_name}_attacher")
|
|
99
|
+
|
|
100
|
+
return false unless signature_matched?(attacher, headers, body)
|
|
101
|
+
|
|
102
|
+
[attacher, result]
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
private
|
|
106
|
+
|
|
107
|
+
def signature_matched?(attacher, headers, body)
|
|
89
108
|
incoming_auth_header = auth_header_hash(headers['Authorization'])
|
|
90
109
|
|
|
91
110
|
signer = build_signer(
|
|
92
111
|
incoming_auth_header['Credential'].split('/'),
|
|
93
|
-
JSON.parse(attacher.record.__send__(:"#{attacher.
|
|
112
|
+
JSON.parse(attacher.record.__send__(:"#{attacher.attribute}") || '{}').dig('metadata', 'key') || 'key',
|
|
94
113
|
headers['x-amz-security-token']
|
|
95
114
|
)
|
|
96
115
|
signature = signer.sign_request(http_method: 'PUT',
|
|
@@ -98,13 +117,10 @@ class Shrine
|
|
|
98
117
|
headers: { 'X-Amz-Date' => headers['X-Amz-Date'] },
|
|
99
118
|
body: body)
|
|
100
119
|
calculated_signature = auth_header_hash(signature.headers['authorization'])['Signature']
|
|
101
|
-
return false if incoming_auth_header['Signature'] != calculated_signature
|
|
102
120
|
|
|
103
|
-
[
|
|
121
|
+
incoming_auth_header['Signature'] == calculated_signature
|
|
104
122
|
end
|
|
105
123
|
|
|
106
|
-
private
|
|
107
|
-
|
|
108
124
|
def build_signer(headers, secret_access_key, security_token = nil)
|
|
109
125
|
Aws::Sigv4::Signer.new(
|
|
110
126
|
service: headers[3],
|
|
@@ -141,8 +157,8 @@ class Shrine
|
|
|
141
157
|
# errors. No more response analysis is performed, because Lambda is invoked asynchronously (note the
|
|
142
158
|
# `invocation_type`: 'Event' in the `invoke` call). The results will be sent by Lambda by HTTP requests to
|
|
143
159
|
# the specified `callbackUrl`.
|
|
144
|
-
def lambda_process
|
|
145
|
-
cached_file = uploaded_file(
|
|
160
|
+
def lambda_process
|
|
161
|
+
cached_file = uploaded_file(file)
|
|
146
162
|
assembly = lambda_default_values
|
|
147
163
|
assembly.merge!(store.lambda_process_versions(cached_file, context))
|
|
148
164
|
function = assembly.delete(:function)
|
|
@@ -150,13 +166,16 @@ class Shrine
|
|
|
150
166
|
raise Error, "Function #{function} not available on Lambda!" unless function_available?(function)
|
|
151
167
|
|
|
152
168
|
prepare_assembly(assembly, cached_file, context)
|
|
153
|
-
assembly[:context] =
|
|
169
|
+
assembly[:context] = { 'record' => [record.class.name, record.id],
|
|
170
|
+
'name' => name,
|
|
171
|
+
'shrine_class' => self.class.name }
|
|
154
172
|
response = lambda_client.invoke(function_name: function,
|
|
155
173
|
invocation_type: 'Event',
|
|
156
174
|
payload: assembly.to_json)
|
|
157
175
|
raise Error, "#{response.function_error}: #{response.payload.read}" if response.function_error
|
|
158
176
|
|
|
159
|
-
|
|
177
|
+
set(cached_file)
|
|
178
|
+
atomic_persist(cached_file)
|
|
160
179
|
end
|
|
161
180
|
|
|
162
181
|
# Receives the `result` hash after Lambda request was authorized. The result could contain an array of
|
|
@@ -164,7 +183,7 @@ class Shrine
|
|
|
164
183
|
# attached file was just moved to the target storage bucket.
|
|
165
184
|
#
|
|
166
185
|
# Deletes the signing key, if it is present in the original file's metadata, converts the result to a JSON
|
|
167
|
-
# string, and writes this string into the `
|
|
186
|
+
# string, and writes this string into the `attribute` of the Shrine attacher's record.
|
|
168
187
|
#
|
|
169
188
|
# Chooses the `save_method` either for the ActiveRecord or for Sequel, and saves the record.
|
|
170
189
|
# @param [Hash] result
|
|
@@ -179,7 +198,7 @@ class Shrine
|
|
|
179
198
|
result.to_json
|
|
180
199
|
end
|
|
181
200
|
|
|
182
|
-
record.__send__(:"#{
|
|
201
|
+
record.__send__(:"#{attribute}=", attr_content)
|
|
183
202
|
save_method = case record
|
|
184
203
|
when ActiveRecord::Base
|
|
185
204
|
:save
|
|
@@ -217,7 +236,7 @@ class Shrine
|
|
|
217
236
|
end
|
|
218
237
|
|
|
219
238
|
def prepare_assembly(assembly, cached_file, context)
|
|
220
|
-
assembly[:path] = store.generate_location(cached_file, context)
|
|
239
|
+
assembly[:path] = store.generate_location(cached_file, metadata: cached_file.metadata, context: context)
|
|
221
240
|
assembly[:storages].each do |s|
|
|
222
241
|
upload_options = get_upload_options(cached_file, context, s)
|
|
223
242
|
s[1][:upload_options] = upload_options if upload_options
|
data/shrine-aws-lambda.gemspec
CHANGED
|
@@ -28,7 +28,7 @@ Gem::Specification.new do |gem|
|
|
|
28
28
|
|
|
29
29
|
gem.add_dependency 'aws-sdk-lambda', '~> 1.0'
|
|
30
30
|
gem.add_dependency 'aws-sdk-s3', '~> 1.2'
|
|
31
|
-
gem.add_dependency 'shrine', '~>
|
|
31
|
+
gem.add_dependency 'shrine', '~> 3.4'
|
|
32
32
|
|
|
33
33
|
gem.add_development_dependency 'activerecord', '>= 4.2.0'
|
|
34
34
|
gem.add_development_dependency 'dotenv'
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: shrine-aws-lambda
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1
|
|
4
|
+
version: 0.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Aurel Branzeanu
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2023-05-15 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: aws-sdk-lambda
|
|
@@ -44,14 +44,14 @@ dependencies:
|
|
|
44
44
|
requirements:
|
|
45
45
|
- - "~>"
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: '
|
|
47
|
+
version: '3.4'
|
|
48
48
|
type: :runtime
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
52
|
- - "~>"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: '
|
|
54
|
+
version: '3.4'
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
56
|
name: activerecord
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|