You are here

public function S3fsService::validate in S3 File System 4.0.x

Same name and namespace in other branches
  1. 8.3 src/S3fsService.php \Drupal\s3fs\S3fsService::validate()

Validate the S3fs config.

Parameters

array $config: Array of configuration settings from which to configure the client.

Return value

array Empty array if configuration is valid, errors array otherwise.

Overrides S3fsServiceInterface::validate

File

src/S3fsService.php, line 87

Class

S3fsService
Defines a S3fsService service.

Namespace

Drupal\s3fs

Code

public function validate(array $config) {
  $errors = [];
  if (!class_exists('Aws\\S3\\S3Client')) {
    $errors[] = $this
      ->t('Cannot load Aws\\S3\\S3Client class. Please ensure that the aws sdk php library is installed correctly.');
  }
  if (!empty($config['credentials_file'])) {
    if (!is_file($config['credentials_file']) || !is_readable($config['credentials_file'])) {
      $errors[] = $this
        ->t("Unable to read Custom Credentials file. Please verify @file exists\n           and permissions are valid.", [
        '@file' => $config['credentials_file'],
      ]);
    }
  }
  if (empty($config['bucket'])) {
    $errors[] = $this
      ->t('Your AmazonS3 bucket name is not configured.');
  }
  if (!empty($config['use_customhost']) && empty($config['hostname'])) {
    $errors[] = $this
      ->t('You must specify a Hostname to use Custom Host feature.');
  }
  if (!empty($config['use_cname']) && empty($config['domain'])) {
    $errors[] = $this
      ->t('You must specify a CDN Domain Name to use CNAME feature.');
  }
  switch ($config['domain_root']) {
    case 'root':
      if (empty($config['root_folder'])) {
        $errors[] = $this
          ->t('You must specify a Root folder to map the Domain Name to it.');
      }
      break;
    default:
      break;
  }
  try {
    $s3 = $this
      ->getAmazonS3Client($config);
  } catch (\Exception $e) {
    $errors[] = $this
      ->t('An unexpected error occurred obtaining S3Client . @message', [
      '@message' => $e
        ->getMessage(),
    ]);
  }

  // Test the connection to S3, bucket name and WRITE|READ ACL permissions.
  // These actions will trigger descriptive exceptions if the credentials,
  // bucket name, or region are invalid/mismatched.
  $date = date('dmy-Hi');
  $key_path = "s3fs-tests-results";
  if (!empty($config['root_folder'])) {
    $key_path = "{$config['root_folder']}/{$key_path}";
  }
  $key = "{$key_path}/write-test-{$date}.txt";
  $successPut = FALSE;
  $successDelete = FALSE;
  $exceptionCaught = FALSE;
  try {
    $putOptions = [
      'Body' => 'Example file uploaded successfully.',
      'Bucket' => $config['bucket'],
      'Key' => $key,
    ];
    if (!empty($config['encryption'])) {
      $putOptions['ServerSideEncryption'] = $config['encryption'];
    }

    // Set the Cache-Control header, if the user specified one.
    if (!empty($config['cache_control_header'])) {
      $putOptions['CacheControl'] = $config['cache_control_header'];
    }
    $s3
      ->putObject($putOptions);
    $object = $s3
      ->getObject([
      'Bucket' => $config['bucket'],
      'Key' => $key,
    ]);
    if ($object) {
      $successPut = TRUE;
      $s3
        ->deleteObject([
        'Bucket' => $config['bucket'],
        'Key' => $key,
      ]);
      $successDelete = TRUE;
    }
  } catch (\Exception $e) {
    $exceptionCaught = $e;
  }
  if (!empty($config['read_only']) && ($successPut || $successDelete)) {

    // We were able to upload or delete a file when bucket is
    // tagged read-only.
    $errors[] = $this
      ->t('The provided credentials are not read-only.');
  }
  elseif ($exceptionCaught) {

    // Bucket is read+write but we had an exception above.
    $errors[] = $this
      ->t('An unexpected error occurred. @message', [
      '@message' => $exceptionCaught
        ->getMessage(),
    ]);
  }
  if (empty($config['read_only']) && !Settings::get('s3fs.upload_as_private')) {
    try {
      $key = "{$key_path}/public-write-test-{$date}.txt";
      $putOptions = [
        'Body' => 'Example public file uploaded successfully.',
        'Bucket' => $config['bucket'],
        'Key' => $key,
        'ACL' => 'public-read',
      ];
      if (!empty($config['encryption'])) {
        $putOptions['ServerSideEncryption'] = $config['encryption'];
      }
      $s3
        ->putObject($putOptions);
      if ($object = $s3
        ->getObject([
        'Bucket' => $config['bucket'],
        'Key' => $key,
      ])) {
        $s3
          ->deleteObject([
          'Bucket' => $config['bucket'],
          'Key' => $key,
        ]);
      }
    } catch (S3Exception $e) {
      $errors[] = $this
        ->t("Could not upload file as publicly accessible. If the bucket security\n          policy is set to BlockPublicAcl ensure that upload_as_private is enabled\n          in your settings.php \$settings['s3fs.upload_as_private'] = TRUE;");
      $errors[] = $this
        ->t('Error message: @message', [
        '@message' => $e
          ->getMessage(),
      ]);
    } catch (\Exception $e) {
      $errors[] = $this
        ->t('An unexpected error occurred. @message', [
        '@message' => $e
          ->getMessage(),
      ]);
    }
  }
  if (empty($config['disable_version_sync'])) {
    $args = $this
      ->getListObjectVersionArgs($config);
    $args['MaxKeys'] = '1';
    try {
      $s3
        ->listObjectVersions($args);
    } catch (\Exception $e) {
      $errors[] = $this
        ->t('Unable to listObjectVersions. Is listObjectVersions supported
           by your bucket? @message', [
        '@message' => $e
          ->getMessage(),
      ]);
    }
  }
  return $errors;
}