Rails - Paperclip can't load s3 bucket name - ruby-on-rails-4

I get the following error ArgumentError, missing required :bucket option
Looks like an error where Paperclip can't load the url because it can't find the :bucket name
I had my s3 credentials hardcoded for the development environment. Everything worked fine. To make the application more secure I moved it.
config\initializers\dev_config.rb
ENV.update YAML.load_file("#{Rails.root}/config/dev_vars.yml")[Rails.env]
config\dev_vars.yml
development:
S3_BUCKET_NAME: "####"
AWS_ACCESS_KEY_ID: "#####"
AWS_SECRET_ACCESS_KEY: "####"
config/environments/development.rb
config.paperclip_defaults = {
:storage => :s3,
:s3_credentials => {
:bucket => ENV['S3_BUCKET_NAME'],
:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
:secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
}
}
I can't seem to figure out what is wrong
I've checked the YAML file is properly formatted
Running ENV['S3_BUCKET_NAME'] in the console gives the correct name
Can anyone help?
EDIT -
What I have done is hardcoded just the bucket name :bucket => "name" And that has worked, however I do not want to hardcode s3 information for security reasons.
Is there a reason the other variables are loaded but not the bucket name?

Related

Save AWS Polly mp3 file to S3

I am trying to send some text to AWS Polly to convert to speech and then save that mp3 file to S3. That part seems to work now.
// Send text to AWS Polly
$client_polly = new Aws\Polly\PollyClient([
'region' => 'us-west-2',
'version' => 'latest',
'credentials' => [
'key' => $aws_useKey,
'secret' => $aws_secret,
]
]);
$text = 'Test. Test. This is a sample text to be synthesized.';
$voice = 'Matthew';
$result_polly = $client_polly->startSpeechSynthesisTask([
'Text' => $text,
'TextType' => 'text',
'OutputFormat' => 'mp3',
'OutputS3BucketName' => $aws_bucket,
'OutputS3KeyPrefix' => 'files/audio/,
'VoiceId' => $voice,
'ACL' => 'public-read'
]);
echo $result_polly['ObjectURL'];
I'm also trying to accomplish couple other things:
Make mp3 file publicly accessible. Currently I have to go to AWS console to
click "Make Public" button. It seems that 'ACL' => 'public-read' doesn't work for me
I need to return full URL of the mp3 file. For some reason $result_polly['ObjectURL']; doesn't get any value.
What am I missing?
There is no ACL field in the StartSpeechSynthesisTask call:
$result = $client->startSpeechSynthesisTask([
'LanguageCode' => 'arb|cmn-CN|cy-GB|da-DK|de-DE|en-AU|en-GB|en-GB-WLS|en-IN|en-US|es-ES|es-MX|es-US|fr-CA|fr-FR|is-IS|it-IT|ja-JP|hi-IN|ko-KR|nb-NO|nl-NL|pl-PL|pt-BR|pt-PT|ro-RO|ru-RU|sv-SE|tr-TR',
'LexiconNames' => ['<string>', ...],
'OutputFormat' => 'json|mp3|ogg_vorbis|pcm', // REQUIRED
'OutputS3BucketName' => '<string>', // REQUIRED
'OutputS3KeyPrefix' => '<string>',
'SampleRate' => '<string>',
'SnsTopicArn' => '<string>',
'SpeechMarkTypes' => ['<string>', ...],
'Text' => '<string>', // REQUIRED
'TextType' => 'ssml|text',
'VoiceId' => 'Aditi|Amy|Astrid|Bianca|Brian|Carla|Carmen|Celine|Chantal|Conchita|Cristiano|Dora|Emma|Enrique|Ewa|Filiz|Geraint|Giorgio|Gwyneth|Hans|Ines|Ivy|Jacek|Jan|Joanna|Joey|Justin|Karl|Kendra|Kimberly|Lea|Liv|Lotte|Lucia|Mads|Maja|Marlene|Mathieu|Matthew|Maxim|Mia|Miguel|Mizuki|Naja|Nicole|Penelope|Raveena|Ricardo|Ruben|Russell|Salli|Seoyeon|Takumi|Tatyana|Vicki|Vitoria|Zeina|Zhiyu', // REQUIRED
]);
Therefore, you will either need to make another call to Amazon S3 to change the ACL of the object, or use an Amazon S3 Bucket Policy to make the bucket (or a path within the bucket) public.
The output location is given in the OutputUri field (NOT OutputUrl -- URI vs URL).

Change base URL of generated S3 link using AWS SDK (PHP)

I want to create presigned S3 URL as mentioned here:
https://docs.aws.amazon.com/aws-sdk-php/v3/guide/service/s3-presigned-url.html
My code is quite similar to the example mentioned in the url:
$sdk = new Aws\Sdk( [
'region' => 'eu-west-2',
'version' => 'latest',
] );
$s3Client = $sdk->createS3();
$cmd = $s3Client->getCommand('GetObject', [
'Bucket' => 'books.com',
'Key' => 'testKey'
]);
$request = $s3Client->createPresignedRequest($cmd, '+20 minutes');
// Get the actual presigned-url
$presignedUrl = (string) $request->getUri();
The above generates urls like so:
https://s3.eu-west-2.amazonaws.com/books.com/testKey?X-Amz-Content-Sha256=....
This is as expected. However my S3 bucket has Static Website Hosting and I use a CNAME record allowing me to use a different base url.
Therefore I want the following URL instead:
http://books.com/my-bucket/testKey?X-Amz-Content-Sha256=....
How can I do this?
You can set the endpoint to your bucket domain name:
$sdk = new Aws\Sdk( [
'region' => 'eu-west-2',
'version' => 'latest',
'endpoint' => 'http://books.com',
'bucket_endpoint' => true
] );
This will generate a signed URL that looks like this:
http://books.com/testKey?X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAI2V4Lxxxxxxxxxxx%2F20171116%2Feu-west-2%2Fs3%2Faws4_request&X-Amz-Date=20171116T191003Z&X-Amz-SignedHeaders=host&X-Amz-Expires=1200&X-Amz-Signature=0b735cb661b1d2e25c7f5b477d4c657f160a85aa53bee3ea91244340f6d37dee

AWS Environment variable provider not accepting credentials

I'm connecting dynamoDb locally using the below code
$dotenv = new Dotenv\Dotenv(dirname(__DIR__, 2));
$dotenv->load();
$this->key = getenv('aws_access_key_id');
$this->secret = getenv('aws_secret_access_key');
$this->dynamodb = new DynamoDbClient([
'profile' => 'default',
'region' => 'us-east-1',
'version' => 'latest',
'credentials' => [
'key' => $this->key,
'secret' => $this->secret,
]
]);
My .env file
aws_access_key_id = ....
aws_secret_access_key = ....
I'm getting this error
Type: Aws\Exception\CredentialsException
Message: Cannot read credentials from /Users/user/.aws/credentials
File: /path/to/project/vendor/aws/aws-sdk-php/src/Credentials/CredentialProvider.php
Line: 394
Tried the basic hard-coding of access key & secret key as well but it doesn't seem to be working rather every time it's fetching from the default path ~/.aws/credentials
TIA
Try without specifying:
'profile' => 'default'
You want to use the default profile that is specified in the credentials file. It is possible the SDK looks at this line and try to open the credentials file and look for default profile. I don't have PHP SDK installed to verify this..
Try to print the environment variable to make sure your application is getting those environment variables.
It is not finding it from those variables. You need to export them before you run this script.
Hope it helps.
EDIT1:
use Aws\Common\Credentials\Credentials;
$credentials = new Credentials('YOUR_ACCESS_KEY', 'YOUR_SECRET_KEY');
//assign these credentials to Dynamodbclient
EDIT2: AWS SDK 3.x follows different way to initialize.
$sdk = new Aws\Sdk([
'credentials' => $credentials,
'region' => 'us-east-1',
'version' => 'latest',
'DynamoDb' => [
'region' => 'us-west-2',
],
]);
$dynamodb = $sdk->createDynamoDb(); // This is dynamodb client

elfinder not displaying directories of AWS S3 with Laravel

I am using barryvdh elfinder package to display all the files and folders from my AWS S3 bucket. In elfinders config I have defined root as follows:
[
'driver' => 'Flysystem',
'path' => '',
'defaults' => array('read' => true, 'write' => true),
'filesystem' => new \League\Flysystem\Filesystem(
new \League\Flysystem\AwsS3v2\AwsS3Adapter( \Aws\S3\S3Client::factory(array(
'key' => 'key',
'secret' => 'secret'
)), 'bucket-name'))
]
This seems to work fine, all the files are being displayed. But the folders are not being listed. If I create a folder, it shows error message, but the folder is being created in the bucket, only it doesnt show any folders.
Can anyone help me with the solution.

Cant upload images to s3 bucket with rails app and paperclip

Hi can anyone point me in the direction of what I am doing wrong. I am trying to upload an image to an S3 bucket in EU region, Ireland, using a rails application in development. This is the error I am getting the error
SocketError in ProductsController
getaddrinfo: nodename nor servname provided, or not known
On the following line : TCPSocket.open(conn_address, conn_port, #local_host, #local_port)
I am using the aws-sdk gem and paperclip 4.2.
Here are some code snippets
In:
config/enviroments/development.rb
config.paperclip_defaults = {
:storage => :s3,
:s3_host_name => "s3-eu-west-1.amazonaws.com",
:s3_credentials => {
:bucket => 'S3_BUCKET_NAME',
:access_key_id => 'AWS_ACCESS_KEY_ID',
:secret_access_key => 'AWS_SECRET_ACCESS_KEY'
}
In
config/aws.yml
development:
AWS_ACCESS_KEY_ID: "xxx"
AWS_SECRET_ACCESS_KEY: "xxx"
S3_BUCKET_NAME: "xxx"
s3_host_name: 's3-eu-west-1.amazonaws.com'
In my model
class Product < ActiveRecord::Base
validates :avatar,
attachment_content_type: { content_type: /\Aimage\/.*\Z/ },
attachment_size: { less_than: 5.megabytes }
has_attached_file :avatar, styles: {
thumb: '100x100>',
square: '200x200#',
medium: '300x300>'
}
end
What am I missing? I have looked at every example I could find online and tried to adjust but with no luck.
Thanks
Try this:
#config/enviroments/development.rb
config.paperclip_defaults = {
:storage => :s3,
:s3_host_name => "s3-eu-west-1.amazonaws.com",
:s3_credentials => {
:bucket => ENV["S3_BUCKET_NAME"],
:access_key_id => ENV["AWS_ACCESS_KEY_ID"],
:secret_access_key => ENV["AWS_SECRET_ACCESS_KEY"]
}
Ok, I've solved this by hardcoding the AWS credentials into the development.rb file. So it looks like the problem was the aws.yml file wasn't being loaded, does anyone have any idea why or how to solve this?
Thanks again