Amazon S3 file control of expiration - amazon-web-services

$cmd = $s3Client->getCommand('GetObject', [
'Bucket' => $bucket,
'Key' => $key
]);
$request = $s3Client->createPresignedRequest($cmd, '+48 hours');
Let's say I have one file name "policy.doc", Im using this code to create direct link in 48 hours for 2 users.
The problem is when 1 user quit and I don't want him can access this file anymore, while the other user can access as usual.
How can I control and make the one who quit cannot access this file?

Related

Net::Amazon::S3::Client Produces Error on initiate_multipart_upload

There seems to be some issue triggering initiate_multipart_upload in Net::Amazon::S3::Client. When I do so, I receive the error:
Can't call method "findvalue" on an undefined value at /usr/local/share/perl5/Net/Amazon/S3/Operation/Object/Upload/Create/Response.pm line 17.
I can do a normal put on the object without any error. All else seems to be functional, with lists of the bucket working, etc. Here is a code snippet of what I'm trying:
use Net::Amazon::S3;
our $s3 = Net::Amazon::S3->new({
aws_access_key_id => $config{'access_key_id'},
aws_secret_access_key => $config{'access_key'},
retry => 1
});
our $s3client = Net::Amazon::S3::Client->new( s3 => $s3 );
my $bucket = $s3client->bucket( name => $bucketName );
my $s3object = $bucket->object( key => 'test.txt' );
print 'Key: ' . $s3object->key;
my $uploadId = $s3object->initiate_multipart_upload;
Net::Amazon::S3::Client doesn't object to creating the bucket or the object.
I've been able to initialize a multipart upload using the Paws::S3 library on this bucket just fine. I switched to Net::Amazon::S3::Client since Paws::S3 seems to get stuck at around the 21% mark of uploading my multipart file.

How to get the AWS S3 bucket location via PHP api call?

I am searching on the internet on how can I get the AWS s3 bucket region with an API call or directly in PHP using their library but have not luck finding the info.
I have the following info available:
Account credentials, bucket name, access key + secret. That is for multiple buckets, that I have access to, and I need to get the region programatically, so logging in to aws console and checking out is not an option.
Assuming you have an instance of the AWS PHP Client in $client, you should be able to find the location with $client->getBucketLocation().
Here is some example code:
<?php
$result = $client->getBucketLocation([
'Bucket' => 'yourBucket',
]);
The result will look like this
[
'LocationConstraint' => 'the-region-of-your-bucket',
]
When you create a S3 client, you can use any of the available regions in AWS, even if it's not one that you use.
$s3Client = new Aws\S3\S3MultiRegionClient([
'version' => 'latest',
'region' => 'us-east-1',
'credentials' => [
'key' => $accessKey,
'secret' => $secretKey,
],
]);
$region = $s3Client->determineBucketRegion($bucketname);

How to get the file from Amazon AWS S3 bucket from URL?

I've created an Amazon S3 bucket and I've uploaded the files/images from mobile phone app. I've to show the posts with a lot of images and the images are automatically bind for image URLs. But I don't know how to get the URL because images should not be public to show directly. How can I show them in my app?
$cmd = $client->getCommand('GetObject',[
'Bucket' => 'myinstaclassbucket',
'Key' => 'e12e682c-936d-4a97-a049-6f104dd7c904.jpg',
]);
$request = $client->createPresignedRequest($cmd,$timetoexpire);
$presignedurl = (string) $request->getUri();
echo $presignedurl;
First of all you need to use AWS PHP SDK. Also make sure you have valid Access key and Secret key.
Than everything is straight forward.
$bucket = 'some-bucket';
$key = 'mainFolder/subFolder/file.xx';
// Init client
$client = new S3Client([
'key' => '*YOUR ACCESS KEY*',
'secret' => '*YOUR SECRET KEY*',
]);
if ($client->doesObjectExists($bucket, $key)) {
// If passing `expire` time you will get signed URL
$url = $client->getObjectUrl($bucket, $key, time() + (60 * 60 * 2));
} else {
$url = null;
}

Location to put credentials file for AWS PHP SDK

I created an EC2 Ubuntu instance.
The following is working using the AWS 2.6 SDK for PHP:
$client = DynamoDbClient::factory(array(
'key' => 'xxx',
'secret' => 'xxx',
'region' => 'eu-west-1'
));
I created a credentials file in ~/.aws/credentials.
I put this in /home/ubuntu/.aws/credentials
[default]
aws_access_key_id=xxx
aws_secret_access_key=xxx
Trying the following does not work and gives an InstanceProfileCredentialsException :
$client = DynamoDbClient::factory(array(
'profile' => 'default',
'region' => 'eu-west-1'
));
There is a user www-data and a user ubuntu.
In what folder should I put the credentials file?
One solution to set the credentials is:
sudo nano /etc/apache2/envvars
add environment variables:
export AWS_ACCESS_KEY_ID="xxx"
export AWS_SECRET_ACCESS_KEY="xxx"
sudo service apache2 restart
After that the following works:
$client = DynamoDbClient::factory(array(
'region' => 'eu-west-1'
));
If you are calling the API from an EC2 instance, you should use IAM roles.
Using IAM roles is the preferred technique for providing credentials
to applications running on Amazon EC2. IAM roles remove the need to
worry about credential management from your application. They allow an
instance to "assume" a role by retrieving temporary credentials from
the EC2 instance's metadata server. These temporary credentials, often
referred to as instance profile credentials, allow access to the
actions and resources that the role's policy allows.
This is way too late, but the solution I found for shared servers where you can't actually use environment vars is to define a custom ini file location, like this:
require (__DIR__.'/AWSSDK/aws-autoloader.php');
use Aws\Credentials\CredentialProvider;
use Aws\S3\S3Client;
$profile = 'default';
$path = '/path/to/credentials';
$provider = CredentialProvider::ini($profile, $path);
$provider = CredentialProvider::memoize($provider);
$client = new \Aws\S3\S3Client([
'version' => 'latest',
'region' => 'us-west-2',
'credentials' => $provider
]);
Note that you could even define different profiles with this method.
Documentation HERE
I have a non-EC2 server that accesses SQS and needs credentials. I can't use envvars because there are various people with differing rights who run on this server and envvars is global. For the same reason I don't think I can use an AWS credential file stored under a user's home (although I also couldn't figure out how to make that work for user www-data.)
What I have done is set up a small file AWS_Creds.php
<?php
define ("AWS_KEY", "MY KEY HERE");
define ("AWS_SECRET", "MY SECRET");
?>
The file is stored outside of the webroot and included with include ('ABSOLUTEPATH/AWS_Creds.php') and I include the hard wired reference to the client factory.
Elegant? No. Done? Yes.
EDIT
I forgot to mention: I gitignore AWS_Creds.php so that it doesn't go into our repo.
basicly you can use like this :
$client = DynamoDbClient::factory(array(
'key' => 'aws_key',
'secret' => 'aws_secret',
'region' => 'us-east-1'
));
but in documentation :
Starting with the AWS SDK for PHP version 2.6.2, you can use an AWS credentials file to specify your credentials. This is a special, INI-formatted file stored under your HOME directory, and is a good way to manage credentials for your development environment. The file should be placed at ~/.aws/credentials, where ~ represents your HOME directory.
and usage :
$dynamoDbClient = DynamoDbClient::factory(array(
'profile' => 'project1',
'region' => 'us-west-2',
));
more info : http://docs.aws.amazon.com/aws-sdk-php/guide/latest/credentials.html
After watch the source code Credential.php in aws/aws-sdk-php/src,
php can not directly access /root folder in default. You can write $_SERVER['HOME']=[your new home path] in your php, and put the credential file in newHomePath/.aws/credentials.
require('vendor/autoload.php');
use Aws\Ec2\Ec2Client;
$credentials = new Aws\Credentials\Credentials('Your Access Key',
'Your Secret Key'); // Place here both key
$ec2Client = new Aws\Ec2\Ec2Client([
'version' => 'latest',
'region' => 'ap-south-1',
'credentials' => $credentials
]);
$result = $ec2Client->describeKeyPairs();
echo '<pre>';
print_r($result);
Reference site : https://docs.aws.amazon.com/aws-sdk-php/v2/guide/credentials.html#passing-credentials-into-a-client-factory-method

Get s3 metadata without getting object

Is it possible to get just the objects custom metadata from S3 without having to get the whole object? I've looked through the AWS SDK PHP 2 and searched google and SO with no clear answer, or maybe just not the answer I'm hoping for.
Thanks.
Maybe this would help for PHP 2? It uses the Guzzle framework which I'm not familiar with.
Executes a HeadObject command: The HEAD operation retrieves metadata from an object without returning the object itself. This operation is useful if you're only interested in an object's metadata. To use HEAD, you must have READ access to the object.
Final attempt using Guzzle framework (untested code):
use Guzzle\Service\Resource\Model
use Aws\Common\Enum\Region;
use Aws\S3\S3Client;
$client = S3Client::factory(array(
"key" => "YOUR ACCESS KEY ID",
"secret" => "YOUR SECRET ACCESS KEY",
"region" => Region::US_EAST_1,
"scheme" => "http",
));
// HEAD object
$headers = $client->headObject(array(
"Bucket" => "your-bucket",
"Key" => "your-key"
));
print_r($headers->toArray());
PHP 1.6.2 Solution
// Instantiate the class
$s3 = new AmazonS3();
$bucket = 'my-bucket' . strtolower($s3->key);
$response = $s3->get_object_metadata($bucket, 'üpløåd/î\'vé nøw béén üpløådéd.txt');
// Success?
var_dump($response['ContentType']);
var_dump($response['Headers']['content-language']);
var_dump($response['Headers']['x-amz-meta-ice-ice-baby']);
Credit to: http://docs.aws.amazon.com/AWSSDKforPHP/latest/#m=AmazonS3/get_object_metadata
Hope that helps!
AWS HEAD Object http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectHEAD.html
use Aws\S3\S3Client;
use Guzzle\Common\Collection;
$client = S3Client::factory(array(
'key' => 'YOUR-AWS-KEY',
'secret' => 'YOUR-SECRET-KEY'
));
// Use Guzzle's toArray() method.
$result = $client->headObject(['Bucket' => 'YOUR-BUCKET-NAME', 'Key' => 'YOUR-FILE-NAME'])->toArray();
print_r($result['Metadata']);