Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove unnecessary scopes and document required scopes #509

Draft
wants to merge 7 commits into
base: develop
Choose a base branch
from
47 changes: 39 additions & 8 deletions data/src/main/java/org/cryptomator/data/cloud/s3/S3Impl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import java.io.IOException
import java.io.OutputStream
import java.util.Date
import java.util.LinkedList
import io.minio.BucketExistsArgs
import io.minio.CopyObjectArgs
import io.minio.CopySource
import io.minio.GetObjectArgs
Expand All @@ -33,9 +32,11 @@ import io.minio.MinioClient
import io.minio.PutObjectArgs
import io.minio.RemoveObjectArgs
import io.minio.RemoveObjectsArgs
import io.minio.Result
import io.minio.StatObjectArgs
import io.minio.errors.ErrorResponseException
import io.minio.messages.DeleteObject
import io.minio.messages.Item
import timber.log.Timber

internal class S3Impl(private val cloud: S3Cloud, private val client: MinioClient, private val context: Context) {
Expand Down Expand Up @@ -74,7 +75,14 @@ internal class S3Impl(private val cloud: S3Cloud, private val client: MinioClien
true
} else {
// if the bucket exists the root folder is there too. Otherwise there is no exists check possible
client.bucketExists(BucketExistsArgs.builder().bucket(cloud.s3Bucket()).build())
try {
requireBucketExists()
return true
} catch (e: NoSuchBucketException) {
return false
} catch (e: BackendException) {
throw FatalBackendException(e)
}
}
} catch (e: ErrorResponseException) {
if (S3CloudApiErrorCodes.NO_SUCH_KEY.value == e.errorResponse().code()) {
Expand Down Expand Up @@ -331,13 +339,32 @@ internal class S3Impl(private val cloud: S3Cloud, private val client: MinioClien

@Throws(NoSuchBucketException::class, BackendException::class)
fun checkAuthentication(): String {
return try {
if (!client.bucketExists(BucketExistsArgs.builder().bucket(cloud.s3Bucket()).build())) {
throw NoSuchBucketException(cloud.s3Bucket())
}
""
requireBucketExists()
return ""
}

@Throws(NoSuchBucketException::class, BackendException::class)
private fun requireBucketExists() {
try {
val returned: Sequence<Result<Item?>?> = ListObjectsArgs.builder() //
.bucket(cloud.s3Bucket()) //
.recursive(true) // //TODO
.maxKeys(1) // Batch size
.build() //
.let { client.listObjectsLimit(it, 1) }
//returned
// |-- <Empty> No elements in bucket
// |-- Result<Err> Any error
// |-- Result<Item>
// |-- "name/.bzEmpty" Web interface folder
// |-- "name/" 0 Byte folder
// |-- "name" 0 or X Byte file
//Note: This implementation depends on listObjects/listObjectsLimit returning elements in a sensible order

val result: Result<Item?> = returned.firstOrNull() ?: return //No item, but above all no exception, ergo: Bucket exists
result.get() //Throw appropriate exception (if any) implicitly through "handleApiError"
} catch (e: ErrorResponseException) {
throw handleApiError(e, "")
throw handleApiError(e, cloud.s3Bucket())
}
}

Expand Down Expand Up @@ -374,3 +401,7 @@ internal class S3Impl(private val cloud: S3Cloud, private val client: MinioClien
}
}
}

fun MinioClient.listObjectsLimit(args: ListObjectsArgs, maxObjects: Int): Sequence<Result<Item?>?> {
return this.listObjects(args).asSequence().constrainOnce().take(maxObjects)
}
Loading