Protect server-managed Android public links
This commit is contained in:
+36
-7
@@ -238,16 +238,16 @@ class PublicShareDialogFragment : DialogFragment() {
|
||||
if (updating()) {
|
||||
binding.publicShareDialogTitle.setText(R.string.share_via_link_edit_title)
|
||||
binding.shareViaLinkNameValue.setText(publicShare?.name)
|
||||
val publicShareStatus = publicShare?.let { PublicShareStatusFormatter.statusFor(it) }
|
||||
|
||||
when (publicShare?.permissions) {
|
||||
RemoteShare.CREATE_PERMISSION_FLAG
|
||||
or RemoteShare.DELETE_PERMISSION_FLAG
|
||||
or RemoteShare.UPDATE_PERMISSION_FLAG
|
||||
or RemoteShare.READ_PERMISSION_FLAG ->
|
||||
when (publicShareStatus?.accessMode) {
|
||||
PublicShareAccessMode.READ_AND_WRITE ->
|
||||
binding.shareViaLinkEditPermissionReadAndWrite.isChecked = true
|
||||
|
||||
RemoteShare.CREATE_PERMISSION_FLAG -> binding.shareViaLinkEditPermissionUploadFiles.isChecked = true
|
||||
else -> binding.shareViaLinkEditPermissionReadOnly.isChecked = true
|
||||
PublicShareAccessMode.UPLOAD_ONLY -> binding.shareViaLinkEditPermissionUploadFiles.isChecked = true
|
||||
PublicShareAccessMode.READ_ONLY -> binding.shareViaLinkEditPermissionReadOnly.isChecked = true
|
||||
PublicShareAccessMode.CUSTOM -> binding.shareViaLinkEditPermissionGroup.clearCheck()
|
||||
null -> binding.shareViaLinkEditPermissionReadOnly.isChecked = true
|
||||
}
|
||||
|
||||
if (publicShare?.isPasswordProtected == true) {
|
||||
@@ -265,12 +265,19 @@ class PublicShareDialogFragment : DialogFragment() {
|
||||
binding.shareViaLinkExpirationValue.text = formattedDate
|
||||
}
|
||||
|
||||
if (publicShareStatus?.isEditableInOcsDialog == false) {
|
||||
applyServerManagedPublicLinkState()
|
||||
}
|
||||
} else {
|
||||
binding.shareViaLinkNameValue.setText(arguments?.getString(ARG_DEFAULT_LINK_NAME, ""))
|
||||
}
|
||||
}
|
||||
|
||||
private fun onSaveShareSetting() {
|
||||
if (isServerManagedPublicLink()) {
|
||||
return
|
||||
}
|
||||
|
||||
// Get data filled by user
|
||||
val publicLinkName = binding.shareViaLinkNameValue.text.toString()
|
||||
var publicLinkPassword: String? = binding.shareViaLinkPasswordValue.text.toString()
|
||||
@@ -826,6 +833,11 @@ class PublicShareDialogFragment : DialogFragment() {
|
||||
QSferaVersion(it, it) // FIXME: check productversion as second parameter, not versionstring
|
||||
}
|
||||
|
||||
if (isServerManagedPublicLink()) {
|
||||
applyServerManagedPublicLinkState()
|
||||
return
|
||||
}
|
||||
|
||||
// Show keyboard to fill the public share name
|
||||
dialog?.window?.setSoftInputMode(
|
||||
WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE or WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
|
||||
@@ -932,6 +944,23 @@ class PublicShareDialogFragment : DialogFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun isServerManagedPublicLink(): Boolean =
|
||||
publicShare?.let { share -> !PublicShareStatusFormatter.statusFor(share).isEditableInOcsDialog } == true
|
||||
|
||||
private fun applyServerManagedPublicLinkState() {
|
||||
binding.shareViaLinkManagedAccessMessage.isVisible = true
|
||||
binding.shareViaLinkEditPermissionGroup.isVisible = false
|
||||
binding.shareViaLinkNameValue.isEnabled = false
|
||||
binding.shareViaLinkPasswordSwitch.isEnabled = false
|
||||
binding.shareViaLinkPasswordValue.isEnabled = false
|
||||
binding.generatePasswordButton.isEnabled = false
|
||||
binding.copyPasswordButton.isEnabled = false
|
||||
binding.shareViaLinkExpirationSwitch.isEnabled = false
|
||||
binding.shareViaLinkExpirationLabel.isEnabled = false
|
||||
binding.shareViaLinkExpirationValue.isEnabled = false
|
||||
binding.saveButton.isEnabled = false
|
||||
}
|
||||
|
||||
private fun isReadOnlyPermission() = binding.shareViaLinkEditPermissionReadOnly.isChecked &&
|
||||
capabilities?.filesSharingPublicPasswordEnforcedReadOnly == CapabilityBooleanType.TRUE
|
||||
|
||||
|
||||
+10
-6
@@ -6,11 +6,14 @@ import eu.qsfera.android.lib.resources.shares.RemoteShare
|
||||
internal object PublicShareStatusFormatter {
|
||||
|
||||
fun statusFor(share: OCShare): PublicShareStatus =
|
||||
PublicShareStatus(
|
||||
accessMode = accessModeFor(share.permissions),
|
||||
isPasswordProtected = share.isPasswordProtected,
|
||||
expirationDateInMillis = share.expirationDate.takeIf { it > 0 }
|
||||
)
|
||||
accessModeFor(share.permissions).let { accessMode ->
|
||||
PublicShareStatus(
|
||||
accessMode = accessMode,
|
||||
isPasswordProtected = share.isPasswordProtected,
|
||||
expirationDateInMillis = share.expirationDate.takeIf { it > 0 },
|
||||
isEditableInOcsDialog = accessMode != PublicShareAccessMode.CUSTOM,
|
||||
)
|
||||
}
|
||||
|
||||
private fun accessModeFor(permissions: Int): PublicShareAccessMode {
|
||||
val canRead = permissions hasPermission RemoteShare.READ_PERMISSION_FLAG
|
||||
@@ -39,7 +42,8 @@ internal object PublicShareStatusFormatter {
|
||||
internal data class PublicShareStatus(
|
||||
val accessMode: PublicShareAccessMode,
|
||||
val isPasswordProtected: Boolean,
|
||||
val expirationDateInMillis: Long?
|
||||
val expirationDateInMillis: Long?,
|
||||
val isEditableInOcsDialog: Boolean,
|
||||
)
|
||||
|
||||
internal enum class PublicShareAccessMode {
|
||||
|
||||
@@ -76,6 +76,21 @@
|
||||
|
||||
</RadioGroup>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/shareViaLinkManagedAccessMessage"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/standard_half_margin"
|
||||
android:layout_marginRight="@dimen/standard_half_margin"
|
||||
android:drawableStart="@drawable/common_error_grey"
|
||||
android:drawablePadding="5dp"
|
||||
android:gravity="center_vertical"
|
||||
android:padding="@dimen/standard_half_padding"
|
||||
android:text="@string/share_via_link_managed_access_message"
|
||||
android:textColor="@color/secondaryTextColor"
|
||||
android:textSize="13sp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/shareViaLinkPasswordSection"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -628,6 +628,7 @@
|
||||
<string name="share_public_link_status_read_and_write">Скачивание / просмотр / загрузка</string>
|
||||
<string name="share_public_link_status_upload_only">Только загрузка</string>
|
||||
<string name="share_public_link_status_custom">Особые права</string>
|
||||
<string name="share_via_link_managed_access_message">Эта ссылка использует доступ, управляемый сервером: например, доступ только для организации или безопасный просмотр без скачивания. Здесь ее можно скопировать или удалить. Изменяйте ее в веб-приложении, чтобы не изменить защиту.</string>
|
||||
<string name="share_public_link_status_password_protected">Защищено паролем</string>
|
||||
<string name="share_public_link_status_no_password">Без пароля</string>
|
||||
<string name="share_public_link_status_expires">Действует до %1$s</string>
|
||||
|
||||
@@ -683,6 +683,7 @@
|
||||
<string name="share_public_link_status_read_and_write">Download / View / Upload</string>
|
||||
<string name="share_public_link_status_upload_only">Upload only</string>
|
||||
<string name="share_public_link_status_custom">Custom access</string>
|
||||
<string name="share_via_link_managed_access_message">This link uses server-managed access, such as organization-only access or secure view without downloads. You can copy or remove it here. Edit it from the web app to avoid changing its protection.</string>
|
||||
<string name="share_public_link_status_password_protected">Password protected</string>
|
||||
<string name="share_public_link_status_no_password">No password</string>
|
||||
<string name="share_public_link_status_expires">Expires %1$s</string>
|
||||
|
||||
+2
@@ -23,6 +23,7 @@ class PublicShareStatusFormatterTest {
|
||||
assertEquals(PublicShareAccessMode.READ_ONLY, status.accessMode)
|
||||
assertFalse(status.isPasswordProtected)
|
||||
assertNull(status.expirationDateInMillis)
|
||||
assertTrue(status.isEditableInOcsDialog)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -62,5 +63,6 @@ class PublicShareStatusFormatterTest {
|
||||
val status = PublicShareStatusFormatter.statusFor(share)
|
||||
|
||||
assertEquals(PublicShareAccessMode.CUSTOM, status.accessMode)
|
||||
assertFalse(status.isEditableInOcsDialog)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user