diff --git a/aws-storage-s3/src/main/java/com/amplifyframework/storage/s3/extensions/StorageExceptionExtensions.kt b/aws-storage-s3/src/main/java/com/amplifyframework/storage/s3/extensions/StorageExceptionExtensions.kt index 9b3f6f4b5c..3c6e0b87f4 100644 --- a/aws-storage-s3/src/main/java/com/amplifyframework/storage/s3/extensions/StorageExceptionExtensions.kt +++ b/aws-storage-s3/src/main/java/com/amplifyframework/storage/s3/extensions/StorageExceptionExtensions.kt @@ -15,6 +15,7 @@ package com.amplifyframework.storage.s3.extensions import com.amplifyframework.storage.StorageException +import com.amplifyframework.storage.StorageFilePermissionException import com.amplifyframework.storage.StoragePathValidationException internal fun StoragePathValidationException.Companion.invalidStoragePathException() = StorageException( @@ -31,3 +32,12 @@ internal fun StoragePathValidationException.Companion.unsupportedStoragePathExce ), "Provided StoragePath not supported by AWS S3 Storage Plugin" ) + +internal fun StorageFilePermissionException.Companion.unableToOverwriteFileException() = StorageException( + "Unable to overwrite this file for download.", + StorageFilePermissionException( + "Unable to overwrite this file for download.", + "Acquire write permission for this file before attempting to overwrite it." + ), + "Acquire write permission for this file before attempting to overwrite it." +) diff --git a/aws-storage-s3/src/main/java/com/amplifyframework/storage/s3/transfer/TransferManager.kt b/aws-storage-s3/src/main/java/com/amplifyframework/storage/s3/transfer/TransferManager.kt index 4561f513e0..94e129237e 100644 --- a/aws-storage-s3/src/main/java/com/amplifyframework/storage/s3/transfer/TransferManager.kt +++ b/aws-storage-s3/src/main/java/com/amplifyframework/storage/s3/transfer/TransferManager.kt @@ -24,8 +24,10 @@ import aws.sdk.kotlin.services.s3.model.ObjectCannedAcl import com.amplifyframework.core.Amplify import com.amplifyframework.core.category.CategoryType import com.amplifyframework.storage.ObjectMetadata +import com.amplifyframework.storage.StorageFilePermissionException import com.amplifyframework.storage.s3.AWSS3StoragePlugin import com.amplifyframework.storage.s3.TransferOperations +import com.amplifyframework.storage.s3.extensions.unableToOverwriteFileException import com.amplifyframework.storage.s3.transfer.worker.RouterWorker import com.amplifyframework.storage.s3.transfer.worker.TransferWorkerFactory import java.io.File @@ -192,6 +194,9 @@ internal class TransferManager( val transferRecordId: Int = uri.lastPathSegment?.toInt() ?: throw IllegalStateException("Invalid TransferRecord ID ${uri.lastPathSegment}") if (file.isFile) { + if (!file.canWrite()) { + throw StorageFilePermissionException.unableToOverwriteFileException() + } logger.warn("Overwriting existing file: $file") file.delete() } diff --git a/core/api/core.api b/core/api/core.api index 6b7539d023..f46f985c68 100644 --- a/core/api/core.api +++ b/core/api/core.api @@ -4212,6 +4212,9 @@ public final class com/amplifyframework/storage/StorageException : com/amplifyfr public fun (Ljava/lang/String;Ljava/lang/Throwable;Ljava/lang/String;)V } +public final class com/amplifyframework/storage/StorageFilePermissionException : com/amplifyframework/AmplifyException { +} + public final class com/amplifyframework/storage/StorageItem { public fun (Ljava/lang/String;JLjava/util/Date;Ljava/lang/String;Ljava/lang/Object;)V public final fun component1 ()Ljava/lang/String; diff --git a/core/src/main/java/com/amplifyframework/storage/StorageFilePermissionException.kt b/core/src/main/java/com/amplifyframework/storage/StorageFilePermissionException.kt new file mode 100644 index 0000000000..fd9a8f9d69 --- /dev/null +++ b/core/src/main/java/com/amplifyframework/storage/StorageFilePermissionException.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +package com.amplifyframework.storage + +import com.amplifyframework.AmplifyException +import com.amplifyframework.annotations.InternalAmplifyApi + +/** + * Exception thrown when the necessary file permissions needed to handle a file have not been granted. + */ +class StorageFilePermissionException @InternalAmplifyApi constructor( + message: String, + recoverySuggestion: String +) : AmplifyException(message, recoverySuggestion) { + @InternalAmplifyApi companion object +}