Skip to content

Commit

Permalink
Upgrade to work with Shrine version 3
Browse files Browse the repository at this point in the history
  • Loading branch information
texpert committed Jul 3, 2022
1 parent 4cd1ced commit f0e800d
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 21 deletions.
2 changes: 1 addition & 1 deletion .github_changelog_generator
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
unreleased=true
future-release=0.1.2
future-release=0.2.0
exclude-labels=duplicate,question,invalid,wontfix,release
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,10 @@ end
Shrine.plugin :activerecord
Shrine.plugin :backgrounding
Shrine.plugin :cached_attachment_data # for forms
Shrine.plugin :logging, logger: Rails.logger

Shrine.logger = Rails.logger
Shrine.plugin :instrumentation

Shrine.plugin :rack_file # for non-Rails apps
Shrine.plugin :remote_url, max_size: 1.gigabyte

Expand Down Expand Up @@ -360,15 +363,15 @@ by the following command:
$ gem build shrine-aws-lambda.gemspec
```

Assuming the version was set to `0.1.2`, a `shrine-aws-lambda-0.1.2.gem` binary file will be generated at the root of
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
the app (repo).

- The binary file shouldn't be added into the `git` tree, it will be pushed into the RubyGems and to the GitHub releases

#### Pushing a new gem release to RubyGems

```bash
$ gem push shrine-aws-lambda-0.1.2.gem # don't forget to specify the correct version number
$ gem push shrine-aws-lambda-0.2.0.gem # don't forget to specify the correct version number
```

#### Crafting the new release on GitHub
Expand Down
37 changes: 26 additions & 11 deletions lib/shrine/plugins/aws_lambda.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,12 @@ def self.load_dependencies(uploader, _opts = {})
module AttacherClassMethods
# Loads the attacher from the data, and triggers its instance AWS Lambda
# processing method. Intended to be used in a background job.
def lambda_process(data)
attacher = load(data)
attacher.lambda_process(data)
def lambda_process(attacher_class, record_class, record_id, name, file_data)
attacher_class = Object.const_get(attacher_class)
record = Object.const_get(record_class).find(record_id) # if using Active Record

attacher = attacher_class.retrieve(model: record, name: name, file: file_data)
attacher.lambda_process
attacher
end

Expand All @@ -85,12 +88,20 @@ def lambda_process(data)
# @return [false] if signature in received headers does't match locally computed AWS signature
def lambda_authorize(headers, body)
result = JSON.parse(body)
attacher = load(result.delete('context'))
context = result['context']

context_record = context['record']
record_class = context_record[0]
record_id = context_record[1]
record = Object.const_get(record_class).find(record_id)
attacher_name = context['name']
attacher = record.send(:"#{attacher_name}_attacher")

incoming_auth_header = auth_header_hash(headers['Authorization'])

signer = build_signer(
incoming_auth_header['Credential'].split('/'),
JSON.parse(attacher.record.__send__(:"#{attacher.data_attribute}") || '{}').dig('metadata', 'key') || 'key',
JSON.parse(attacher.record.__send__(:"#{attacher.attribute}") || '{}').dig('metadata', 'key') || 'key',
headers['x-amz-security-token']
)
signature = signer.sign_request(http_method: 'PUT',
Expand Down Expand Up @@ -141,30 +152,34 @@ module AttacherMethods
# errors. No more response analysis is performed, because Lambda is invoked asynchronously (note the
# `invocation_type`: 'Event' in the `invoke` call). The results will be sent by Lambda by HTTP requests to
# the specified `callbackUrl`.
def lambda_process(data)
cached_file = uploaded_file(data['attachment'])
def lambda_process
cached_file = uploaded_file(self.file)
assembly = lambda_default_values
assembly.merge!(store.lambda_process_versions(cached_file, context))
function = assembly.delete(:function)
raise Error, 'No Lambda function specified!' unless function
raise Error, "Function #{function} not available on Lambda!" unless function_available?(function)

prepare_assembly(assembly, cached_file, context)
assembly[:context] = data.except('attachment', 'action', 'phase')
assembly[:context] = { 'record' => [self.record.class.name, self.record.id],
'name' => self.name,
'shrine_class' => self.class.name }
response = lambda_client.invoke(function_name: function,
invocation_type: 'Event',
payload: assembly.to_json)
raise Error, "#{response.function_error}: #{response.payload.read}" if response.function_error

swap(cached_file) || _set(cached_file)
# swap(cached_file) || _set(cached_file)
set(cached_file)
atomic_persist(cached_file)
end

# Receives the `result` hash after Lambda request was authorized. The result could contain an array of
# processed file versions data hashes, or a single file data hash, if there were no versions and the original
# attached file was just moved to the target storage bucket.
#
# Deletes the signing key, if it is present in the original file's metadata, converts the result to a JSON
# string, and writes this string into the `data_attribute` of the Shrine attacher's record.
# string, and writes this string into the `attribute` of the Shrine attacher's record.
#
# Chooses the `save_method` either for the ActiveRecord or for Sequel, and saves the record.
# @param [Hash] result
Expand All @@ -179,7 +194,7 @@ def lambda_save(result)
result.to_json
end

record.__send__(:"#{data_attribute}=", attr_content)
record.__send__(:"#{attribute}=", attr_content)
save_method = case record
when ActiveRecord::Base
:save
Expand Down
2 changes: 1 addition & 1 deletion lib/shrine/plugins/aws_lambda/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
class Shrine
module Plugins
module AwsLambda
VERSION = '0.1.2'
VERSION = '0.2.0'
end
end
end
2 changes: 1 addition & 1 deletion shrine-aws-lambda.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Gem::Specification.new do |gem|

gem.add_dependency 'aws-sdk-lambda', '~> 1.0'
gem.add_dependency 'aws-sdk-s3', '~> 1.2'
gem.add_dependency 'shrine', '~> 2.6'
gem.add_dependency 'shrine', '~> 3.4'

gem.add_development_dependency 'activerecord', '>= 4.2.0'
gem.add_development_dependency 'dotenv'
Expand Down
6 changes: 3 additions & 3 deletions spec/shrine/plugins/aws_lambda_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
require 'active_record'
require 'shrine'
require 'shrine/plugins/activerecord'
require 'shrine/plugins/logging'
require 'shrine/plugins/instrumentation'
require 'shrine/storage/s3'
require 'shrine/plugins/aws_lambda'

Expand Down Expand Up @@ -61,7 +61,7 @@ def lambda_process_versions(io, context)

context 'when Shrine logger is enabled' do
it 'logs the unsupported options' do
shrine.plugin :logging
shrine.plugin :instrumentation

expect_logged("The :unknown_key option is not supported by the Lambda plugin\n", shrine) do
shrine.plugin :aws_lambda, option
Expand Down Expand Up @@ -157,7 +157,7 @@ def lambda_process_versions(io, context)
before do
user.save!

allow(Shrine::Attacher).to receive(:load).and_call_original
allow(Shrine::Attacher).to receive(:from_data).and_call_original
end

context 'when signature in received headers matches locally computed AWS signature' do
Expand Down
2 changes: 1 addition & 1 deletion spec/support/uploaders_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def configure_uploader_class(uploader)
uploader.plugin :backgrounding
uploader.plugin :aws_lambda, settings

uploader::Attacher.promote do |data|
uploader::Attacher.promote_block do |data|
uploader::Attacher.lambda_process(data)
end

Expand Down

0 comments on commit f0e800d

Please sign in to comment.