AWS S3 сделать любой новый добавленный файл публичным - PullRequest
0 голосов
/ 11 июня 2018

У меня есть корзина AWS S3, в которую AWS SES перемещает необработанные электронные письма.моя проблема в том, что эти электронные письма не являются общедоступными по умолчанию, и мне нужен скрипт php, который у меня есть, который берет необработанные файлы из этой корзины S3 и помещает их в mysql, чтобы сделать это без необходимости вручную помечать файлы как публичные.в папке.

Таким образом, используя мой приведенный ниже код, который я использую ключ IAM и секрет IAM, как я могу заставить мой скрипт ниже загружаться в корзину AWS с правильными разрешениями, чтобы иметь возможность получить верхние необработанные файлы?

 //mysql connection 
  $servername = "***>rds.amazonaws.com";
  $username = "****";
  $password ="***";
  $databasename ="***";

  $rightnowdatetimeis = date('Y-m-d H:i:s');
  $rightnowdateis = date('Y-m-d');

$con = mysqli_connect("$servername","$username","$password","$databasename");

if (mysqli_connect_errno())
{
  echo "Failed to connect to MySQL: " . mysqli_connect_error();
}


//load the php mime parse library
require_once __DIR__.'/vendor/autoload.php';

$Parser = new PhpMimeMailParser\Parser();


//Include the AWS SDK using the Composer autoloader.
require 'awssdk/aws-autoloader.php';

use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
// AWS Info
$bucketName = 'pipedemail';
$IAM_KEY = '****';
$IAM_SECRET = '***';
// Connect to AWS
try {
    // You may need to change the region. It will say in the URL when the bucket is open
    // and on creation. us-east-2 is Ohio, us-east-1 is North Virgina
    $s3 = S3Client::factory(
        array(
            'credentials' => array(
                'key' => $IAM_KEY,
                'secret' => $IAM_SECRET
            ),
            'version' => 'latest',
            'region'  => 'us-east-1'
        )
    );
} catch (Exception $e) {
    // We use a die, so if this fails. It stops here. Typically this is a REST call so this would
    // return a json object.
    die("Error: " . $e->getMessage());
}

// Use the high-level iterators (returns ALL of your objects).
$objects = $s3->getIterator('ListObjects', array('Bucket' => $bucketName));

foreach ($objects as $object) 
{
    $objectkey = $object['Key'];

    // Get the object
    $result = $s3->getObject(array(
       'Bucket' => $bucketName,
       'Key'    => $objectkey
    ));

    //lets get the raw email file to parse it
    //$Parser->setText($result['Body']);

    //echo "$objectkey";
    $path = "*****";

    //lets get the raw email file to parse it
    $Parser->setText(file_get_contents($path));

    // Once we've indicated where to find the mail, we can parse out the data
    //$to = $Parser->getHeader('to');             // "test" <test@example.com>, "test2" <test2@example.com>
     $addressesTo = $Parser->getAddresses('to'); //Return an array : [[test, test@example.com, false],[test2, test2@example.com, false]]
     $tobrand = $addressesTo[0]['address'];

     $to_brand_domainname = explode("@", "$tobrand", 2)[1]; 
     //lets get the brandid based on the to domain name
     $brandsql = mysqli_query($con, "SELECT brandid FROM brands WHERE branddomainname='$to_brand_domainname' LIMIT 1");
     $brandrow = mysqli_fetch_array($brandsql);
     $brandid = $brandrow['brandid'];

     $from = $Parser->getHeader('from');             // John Smith
     //lets break the full name into a lastname and firstname veriable
     $namepieces = explode(" ", $from);
     $first_name = $namepieces[0];
     $last_name = $namepieces[1];

     $addressesFrom = $Parser->getAddresses('from'); //Return an array : test, test@example.com, false
     $fromname = $addressesFrom[0]['display']; //not sure what this returns yet

     $fromemail = $addressesFrom[0]['address'];
     $subject = $Parser->getHeader('subject');


    //html of email body
    $html_emailbody = $Parser->getMessageBody('html');
   // $htmlEmbedded = $Parser->getMessageBody('htmlEmbedded'); //HTML Body included data


   //First lets see if this email address exists within the database 
    $emailsql = mysqli_query($con, "SELECT cid FROM customer_profiles WHERE email_address='$fromemail' LIMIT 1");
    $erow = mysqli_fetch_assoc($emailsql);
    $cid = $erow['cid'];

   //if customer does not exists
     if($cid < 1)
     {
          $customsql = mysqli_query($con, "INSERT into customer_profiles(first_name, last_name, email_address, last_contact_date) 
                       VALUES('$first_name','$last_name','$fromemail','$rightnowdateis')");
          $cid = mysqli_insert_id($con);
     }

   //create the support issue
     $sql = mysqli_query($con, "INSERT into product_issues(cid, date_created, brandid) VALUES('$cid','$rightnowdatetimeis','$brandid')");
     $issueid = mysqli_insert_id($con);


     mysqli_query($con, "INSERT into customer_notes(cid, date_written, note_body, issueid, note_type, brandid, note_subject, note_status) 
                           VALUES('$cid','$rightnowdatetimeis','$html_emailbody','$issueid','email','$brandid','$subject','unread')");
     $noteid = mysqli_insert_id($con);

    //Pass in a writeable path to save attachments
     $attach_dir = 'email_attachments/';     // Be sure to include the trailing slash
    //$include_inline = false;             // Optional argument to include inline attachments (default: true)
    //$Parser->saveAttachments($attach_dir [,$include_inline]);
    // $Parser->saveAttachments($attach_dir);

    // Get an array of Attachment items from $Parser
    // $attachments = $Parser->getAttachments([$include_inline]);

    //  Loop through all the Attachments
     //   if(count($attachments) > 0) 
     //    {
      //       foreach ($attachments as $attachment) 
      //       {
       //        $fileattachmentname = $attachment->getFilename();
        //        $attachment_filetype = $attachment->getContentType();

            //save file attachement name to database
         //       mysqli_query($con, "INSERT into email_attachments(attachment_name, attachment_filetype, cid, noteid, issueid) 
         //                            VALUES('$fileattachmentname','$attachment_filetype','$cid','$noteid','$issueid')");

            //echo 'Filename : '.$attachment->getFilename().'<br />'; // logo.jpg
            //echo 'Filesize : '.filesize($attach_dir.$attachment->getFilename()).'<br />'; // 1000
            //echo 'Filetype : '.$attachment->getContentType().'<br />'; // image/jpeg
            //echo 'MIME part string : '.$attachment->getMimePartStr().'<br />'; // (the whole MIME part of the attachment)
         //   }
      //  }

    //now lets delete the object since we already took the email and saved it into mysql
    $s3->deleteObject(array('Bucket' => $bucketName, 'Key' => $objectkey)); 
}

Ответы [ 2 ]

0 голосов
/ 11 июня 2018

если вы хотите публичный доступ для чтения к вашему ведру, то эта политика сделает это

{
  "Version":"2012-10-17",
  "Statement":[
    {
      "Sid":"AddPerm",
      "Effect":"Allow",
      "Principal": "*",
      "Action":["s3:GetObject"],
      "Resource":["arn:aws:s3:::examplebucket/*"]
    }
  ]
}

Но то, что вы хотите сделать с вашими электронными письмами, то есть публичный доступ на чтение к корзинам, делается с помощьюсправка ACL , то есть Списки контроля доступа , и вам не нужно предоставлять публичный доступ на чтение к корзине, потому что ваш случай требует публичного доступа на чтение к объектам, то есть только к электронной почте.

При сохранении объекта в s3 вы можете установить ACL для этого объекта на public-read в своем коде, чтобы выполнить свою работу

пример на python для загрузки изображенияс открытым доступом для чтения с использованием ACL

import boto3    

s3client=boto3.client('s3')
s3client.upload_file('filename', 'bucket-name', ktr,ExtraArgs={'ACL': 'public-read'})

Подробнее об ACL можно узнать по этой ссылке

https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html

0 голосов
/ 11 июня 2018

Я знаю, что вы уже упоминали о проблемах безопасности, но я хочу еще раз повторить, что вы не просто предоставляете открытый доступ для чтения, но, похоже, вы пытаетесь разрешить любой s3 action.Вы не просто открываете себя тому, кто читает ваши данные (что вас не беспокоит), но также пишете свои собственные данные или манипулируете вашими данными.Вы действительно не хотите, чтобы корзина, которая может масштабироваться до бесконечного размера, была доступна для записи всей публике, и вдвойне, так что если вы собираетесь обрабатывать то, что там написано.

Вы должны серьезнопосмотрите, как работают ведущие списки ACL, и рассмотрите возможность использования учетных данных IAM или ролей экземпляра (если сервер обрабатывает данные также в AWS) , чтобы обеспечить безопасную обработку данных электронной почты.Ничто не мешает вам использовать политики IAM, чтобы все, кто обрабатывает эти данные, могли безопасно читать и записывать в этот сегмент.Существует множество причин, по которым AWS вставляет предупреждения о том, что не делает это во всей документации.

...