Ask user to re-grant local storage permission when revoked #251

This commit is contained in:
Julian Raufelder 2021-10-28 17:41:19 +02:00
parent fda2927603
commit 250d756917
No known key found for this signature in database
GPG Key ID: 17EE71F6634E381D
5 changed files with 67 additions and 13 deletions

View File

@ -340,7 +340,7 @@ internal class LocalStorageAccessFrameworkImpl(context: Context, private val mim
file.parent.uri?.let {
val mimeType = if (mimeTypes.fromFilename(file.name) == null) MimeType.APPLICATION_OCTET_STREAM else mimeTypes.fromFilename(file.name)
try {
DocumentsContract.createDocument(contentResolver(), it, mimeType.toString(), file.name) // FIXME
DocumentsContract.createDocument(contentResolver(), it, mimeType.toString(), file.name)
} catch (e: FileNotFoundException) {
null
}

View File

@ -1,6 +1,9 @@
package org.cryptomator.presentation.presenter
import android.accounts.AccountManager
import android.content.Intent
import android.content.Intent.ACTION_OPEN_DOCUMENT_TREE
import android.provider.DocumentsContract
import android.widget.Toast
import com.dropbox.core.android.Auth
import org.cryptomator.data.cloud.onedrive.OnedriveClientFactory
@ -432,6 +435,7 @@ class AuthenticateCloudPresenter @Inject constructor( //
private inner class LocalStorageAuthStrategy : AuthStrategy {
private var authenticationStarted = false
override fun supports(cloud: CloudModel): Boolean {
return cloud.cloudType() == CloudTypeModel.LOCAL
}
@ -444,19 +448,43 @@ class AuthenticateCloudPresenter @Inject constructor( //
private fun startAuthentication(cloud: CloudModel) {
authenticationStarted = true
val uri = (cloud as LocalStorageModel).uri()
val permissions = context().contentResolver.persistedUriPermissions
for (permission in permissions) {
if (permission.uri.toString() == (cloud as LocalStorageModel).uri()) {
if (permission.uri.toString() == uri) {
succeedAuthenticationWith(cloud.toCloud())
}
}
// FIXME think about how to re-request permission
// FIXME change in the FOSS variant too
failAuthentication(PermissionNotGrantedException(R.string.permission_snackbar_auth_local_vault))
Timber.tag("AuthicateCloudPrester").e("Permission revoked, ask to re-pick location")
Toast.makeText(context(), getString(R.string.permission_revoked_re_request_permission), Toast.LENGTH_LONG).show()
val openDocumentTree = Intent(ACTION_OPEN_DOCUMENT_TREE).apply {
putExtra(DocumentsContract.EXTRA_INITIAL_URI, uri)
}
requestActivityResult(ActivityResultCallbacks.rePickedLocalStorageLocation(cloud), openDocumentTree)
}
}
@Callback
fun rePickedLocalStorageLocation(result: ActivityResult, cloud: LocalStorageModel) {
val rootTreeUriOfLocalStorage = result.intent().data
rootTreeUriOfLocalStorage?.let {
context() //
.contentResolver //
.takePersistableUriPermission( //
it, //
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
)
}
Timber.tag("AuthicateCloudPrester").e("Permission granted again")
succeedAuthenticationWith(cloud.toCloud())
}
private fun encrypt(password: String): String {
return CredentialCryptor //
.getInstance(context()) //

View File

@ -289,10 +289,6 @@ class CloudConnectionListPresenter @Inject constructor( //
}
}
fun onDefaultLocalCloudConnectionClicked() {
finishWithResult(SELECTED_CLOUD, defaultLocalStorageCloud)
}
companion object {
const val SELECTED_CLOUD = "selectedCloudConnection"

View File

@ -61,6 +61,8 @@
<string name="permission_message_upload_file">Cryptomator needs storage access to upload files</string>
<string name="permission_message_share_file">Cryptomator needs storage access to share files</string>
<string name="permission_revoked_re_request_permission">Cryptomator has lost permission to access this location. Please select this folder again to restore the permission.</string>
<string name="snack_bar_action_title_settings">Settings</string>
<string name="snack_bar_action_title_search">Search</string>
<string name="snack_bar_action_title_search_previous">Previous</string>

View File

@ -2,6 +2,9 @@ package org.cryptomator.presentation.presenter
import android.accounts.AccountManager
import android.content.ActivityNotFoundException
import android.content.Intent
import android.content.Intent.ACTION_OPEN_DOCUMENT_TREE
import android.provider.DocumentsContract
import android.widget.Toast
import com.dropbox.core.android.Auth
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential
@ -478,6 +481,7 @@ class AuthenticateCloudPresenter @Inject constructor( //
private inner class LocalStorageAuthStrategy : AuthStrategy {
private var authenticationStarted = false
override fun supports(cloud: CloudModel): Boolean {
return cloud.cloudType() == CloudTypeModel.LOCAL
}
@ -490,19 +494,43 @@ class AuthenticateCloudPresenter @Inject constructor( //
private fun startAuthentication(cloud: CloudModel) {
authenticationStarted = true
val uri = (cloud as LocalStorageModel).uri()
val permissions = context().contentResolver.persistedUriPermissions
for (permission in permissions) {
if (permission.uri.toString() == (cloud as LocalStorageModel).uri()) {
if (permission.uri.toString() == uri) {
succeedAuthenticationWith(cloud.toCloud())
}
}
// FIXME think about how to re-request permission
// FIXME change in the FOSS variant too
failAuthentication(PermissionNotGrantedException(R.string.permission_snackbar_auth_local_vault))
Timber.tag("AuthicateCloudPrester").e("Permission revoked, ask to re-pick location")
Toast.makeText(context(), getString(R.string.permission_revoked_re_request_permission), Toast.LENGTH_LONG).show()
val openDocumentTree = Intent(ACTION_OPEN_DOCUMENT_TREE).apply {
putExtra(DocumentsContract.EXTRA_INITIAL_URI, uri)
}
requestActivityResult(ActivityResultCallbacks.rePickedLocalStorageLocation(cloud), openDocumentTree)
}
}
@Callback
fun rePickedLocalStorageLocation(result: ActivityResult, cloud: LocalStorageModel) {
val rootTreeUriOfLocalStorage = result.intent().data
rootTreeUriOfLocalStorage?.let {
context() //
.contentResolver //
.takePersistableUriPermission( //
it, //
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
)
}
Timber.tag("AuthicateCloudPrester").e("Permission granted again")
succeedAuthenticationWith(cloud.toCloud())
}
private fun encrypt(password: String): String {
return CredentialCryptor //
.getInstance(context()) //