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

[SPACES] WebDAV permissions in files #3997

Merged
merged 6 commits into from
Apr 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ import com.owncloud.android.presentation.settings.security.SettingsSecurityFragm
import com.owncloud.android.ui.activity.FileDisplayActivity.Companion.ALL_FILES_SAF_REGEX
import com.owncloud.android.ui.dialog.ShareLinkToDialog
import com.owncloud.android.utils.MimetypeIconUtil
import com.owncloud.android.utils.UriUtilsKt
import com.owncloud.android.utils.UriUtilsKt.getExposedFileUriForOCFile
import timber.log.Timber
import java.io.File
Expand Down Expand Up @@ -374,10 +373,10 @@ fun FragmentActivity.sendDownloadedFilesByShareSheet(ocFiles: List<OCFile>) {
val sendIntent = if (ocFiles.size == 1) {
Intent(Intent.ACTION_SEND).apply {
type = ocFiles.first().mimeType
putExtra(Intent.EXTRA_STREAM, UriUtilsKt.getExposedFileUriForOCFile(this@sendDownloadedFilesByShareSheet, ocFiles.first()))
putExtra(Intent.EXTRA_STREAM, getExposedFileUriForOCFile(this@sendDownloadedFilesByShareSheet, ocFiles.first()))
}
} else {
val fileUris = ocFiles.map { UriUtilsKt.getExposedFileUriForOCFile(this@sendDownloadedFilesByShareSheet, it) }
val fileUris = ocFiles.map { getExposedFileUriForOCFile(this@sendDownloadedFilesByShareSheet, it) }
Intent(Intent.ACTION_SEND_MULTIPLE).apply {
type = ALL_FILES_SAF_REGEX
putParcelableArrayListExtra(Intent.EXTRA_STREAM, ArrayList(fileUris))
Expand All @@ -402,7 +401,10 @@ fun FragmentActivity.sendDownloadedFilesByShareSheet(ocFiles: List<OCFile>) {
fun Activity.openOCFile(ocFile: OCFile) {
val intentForSavedMimeType = Intent(Intent.ACTION_VIEW).apply {
setDataAndType(getExposedFileUriForOCFile(this@openOCFile, ocFile), ocFile.mimeType)
flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
if (ocFile.hasWritePermission) {
flags = flags or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
}
}

try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import androidx.fragment.app.FragmentActivity;
import androidx.work.WorkInfo;
import androidx.work.WorkManager;
import com.google.common.collect.Iterables;
import com.owncloud.android.R;
import com.owncloud.android.domain.availableoffline.model.AvailableOfflineStatus;
import com.owncloud.android.domain.capabilities.model.OCCapability;
Expand Down Expand Up @@ -120,19 +121,31 @@ public void filter(Menu menu, boolean displaySelectAll, boolean displaySelectInv
boolean onlyAvailableOffline, boolean sharedByLinkFiles) {
if (mFiles == null || mFiles.size() <= 0) {
hideAll(menu);

} else {
List<Integer> toShow = new ArrayList<>();
List<Integer> toHide = new ArrayList<>();

filter(toShow, toHide, displaySelectAll, displaySelectInverse, onlyAvailableOffline, sharedByLinkFiles);

boolean hasWritePermission;
if (mFiles.size() == 1) {
hasWritePermission = mFiles.get(0).getHasWritePermission();
} else {
hasWritePermission = false;
}
MenuItem item;
for (int i : toShow) {
item = menu.findItem(i);
if (item != null) {
item.setVisible(true);
item.setEnabled(true);
if (i == R.id.action_open_file_with) {
if (!hasWritePermission) {
item.setTitle(R.string.actionbar_open_with_read_only);
} else {
item.setTitle(R.string.actionbar_open_with);
}
}
}
}

Expand Down Expand Up @@ -201,27 +214,37 @@ private void filter(List<Integer> toShow, List<Integer> toHide, boolean displayS
}

// RENAME
if (!isSingleSelection() || synchronizing || videoPreviewing || onlyAvailableOffline || sharedByLinkFiles) {
boolean hasRenamePermission;
if (mFiles.size() == 1) {
hasRenamePermission = mFiles.get(0).getHasRenamePermission();
} else {
hasRenamePermission = false;
}
if (!isSingleSelection() || synchronizing || videoPreviewing || onlyAvailableOffline || sharedByLinkFiles || !hasRenamePermission) {
toHide.add(R.id.action_rename_file);

} else {
toShow.add(R.id.action_rename_file);
}

// MOVE & COPY
if (mFiles.isEmpty() || synchronizing || videoPreviewing || onlyAvailableOffline || sharedByLinkFiles) {
// MOVE
boolean hasMovePermission = Iterables.all(mFiles, OCFile::getHasMovePermission);
if (mFiles.isEmpty() || synchronizing || videoPreviewing || onlyAvailableOffline || sharedByLinkFiles || !hasMovePermission) {
toHide.add(R.id.action_move);
toHide.add(R.id.action_copy);

} else {
toShow.add(R.id.action_move);
}

// COPY
if (mFiles.isEmpty() || synchronizing || videoPreviewing || onlyAvailableOffline || sharedByLinkFiles) {
toHide.add(R.id.action_copy);
} else {
toShow.add(R.id.action_copy);
}

// REMOVE
if (mFiles.isEmpty() || synchronizing || onlyAvailableOffline || sharedByLinkFiles) {
boolean hasDeletePermission = Iterables.all(mFiles, OCFile::getHasDeletePermission);
if (mFiles.isEmpty() || synchronizing || onlyAvailableOffline || sharedByLinkFiles || !hasDeletePermission) {
toHide.add(R.id.action_remove_file);

} else {
toShow.add(R.id.action_remove_file);
}
Expand Down Expand Up @@ -263,8 +286,14 @@ private void filter(List<Integer> toShow, List<Integer> toHide, boolean displayS
OCSpace space = mComponentsGetter.getStorageManager().getSpace(mFiles.get(0).getSpaceId(), mAccount.name);
boolean notPersonalSpace = space != null && !space.isPersonal();

boolean hasResharePermission;
if (mFiles.size() == 1) {
hasResharePermission = mFiles.get(0).getHasResharePermission();
} else {
hasResharePermission = false;
}
if ((!shareViaLinkAllowed && !shareWithUsersAllowed) || !isSingleSelection() ||
notAllowResharing || onlyAvailableOffline || notPersonalSpace) {
notAllowResharing || onlyAvailableOffline || notPersonalSpace || !hasResharePermission) {
toHide.add(R.id.action_share_file);
} else {
toShow.add(R.id.action_share_file);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ class FileDetailsFragment : FileFragment() {
false,
false,
false,
false
false,
)

menu.findItem(R.id.action_see_details)?.apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,18 @@ public FileOperationsHelper(FileActivity fileActivity) {
mFileActivity = fileActivity;
}

private Intent getIntentForSavedMimeType(Uri data, String type) {
private Intent getIntentForSavedMimeType(Uri data, String type, boolean hasWritePermission) {
Intent intentForSavedMimeType = new Intent(Intent.ACTION_VIEW);
intentForSavedMimeType.setDataAndType(data, type);
intentForSavedMimeType.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
int flags = Intent.FLAG_GRANT_READ_URI_PERMISSION;
if (hasWritePermission) {
flags = flags | Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
}
intentForSavedMimeType.setFlags(flags);
return intentForSavedMimeType;
}

private Intent getIntentForGuessedMimeType(String storagePath, String type, Uri data) {
private Intent getIntentForGuessedMimeType(String storagePath, String type, Uri data, boolean hasWritePermission) {
Intent intentForGuessedMimeType = null;

if (storagePath != null && storagePath.lastIndexOf('.') >= 0) {
Expand All @@ -80,7 +84,11 @@ private Intent getIntentForGuessedMimeType(String storagePath, String type, Uri
if (guessedMimeType != null && !guessedMimeType.equals(type)) {
intentForGuessedMimeType = new Intent(Intent.ACTION_VIEW);
intentForGuessedMimeType.setDataAndType(data, guessedMimeType);
intentForGuessedMimeType.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
int flags = Intent.FLAG_GRANT_READ_URI_PERMISSION;
if (hasWritePermission) {
flags = flags | Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
}
intentForGuessedMimeType.setFlags(flags);
}
}
return intentForGuessedMimeType;
Expand All @@ -89,10 +97,10 @@ private Intent getIntentForGuessedMimeType(String storagePath, String type, Uri
public void openFile(OCFile ocFile) {
if (ocFile != null) {
Intent intentForSavedMimeType = getIntentForSavedMimeType(UriUtilsKt.INSTANCE.getExposedFileUriForOCFile(mFileActivity, ocFile),
ocFile.getMimeType());
ocFile.getMimeType(), ocFile.getHasWritePermission());

Intent intentForGuessedMimeType = getIntentForGuessedMimeType(ocFile.getStoragePath(), ocFile.getMimeType(),
UriUtilsKt.INSTANCE.getExposedFileUriForOCFile(mFileActivity, ocFile));
UriUtilsKt.INSTANCE.getExposedFileUriForOCFile(mFileActivity, ocFile), ocFile.getHasWritePermission());

openFileWithIntent(intentForSavedMimeType, intentForGuessedMimeType);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ class PreviewAudioFragment : FileFragment() {
false,
false,
false,
false
false,
)

// additional restriction for this fragment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,13 @@ class PreviewImageFragment : FileFragment() {
mContainerActivity,
activity
)
fileMenuFilter.filter(menu, false, false, false, false)
fileMenuFilter.filter(
menu,
false,
false,
false,
false,
)
}

// additional restriction for this fragment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,13 @@ public void onPrepareOptionsMenu(Menu menu) {
mContainerActivity,
getActivity()
);
mf.filter(menu, false, false, false, false);
mf.filter(
menu,
false,
false,
false,
false
);
}

// additional restriction for this fragment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,13 @@ public void onPrepareOptionsMenu(@NonNull Menu menu) {
mContainerActivity,
getActivity()
);
mf.filter(menu, false, false, false, false);
mf.filter(
menu,
false,
false,
false,
false
);

// additional restrictions for this fragment

Expand Down
4 changes: 2 additions & 2 deletions owncloudApp/src/main/res/menu/file_actions_menu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,13 @@
android:id="@+id/action_move"
android:title="@string/actionbar_move"
android:icon="@drawable/ic_action_move"
app:showAsAction="ifRoom"
app:showAsAction="never"
android:orderInCategory="1" />
<item
android:id="@+id/action_copy"
android:title="@android:string/copy"
android:icon="@drawable/ic_action_copy"
app:showAsAction="ifRoom"
app:showAsAction="never"
android:orderInCategory="1" />
<item
android:id="@+id/action_rename_file"
Expand Down
1 change: 1 addition & 0 deletions owncloudApp/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<string name="actionbar_upload_from_apps">Content from other apps</string>
<string name="actionbar_upload_files">Files</string>
<string name="actionbar_open_with">Open with</string>
<string name="actionbar_open_with_read_only">Open with (read only)</string>
<string name="actionbar_mkdir">New folder</string>
<string name="actionbar_settings">Settings</string>
<string name="actionbar_see_details">Details</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,30 @@ data class OCFile(
val isText: Boolean
get() = isOfType(MIME_PREFIX_TEXT)

/**
* @return 'True' if the file has the 'W' (can write) within its group of permissions
*/
val hasWritePermission: Boolean
get() = permissions?.contains(char = 'W', ignoreCase = true) ?: false

/**
* @return 'True' if the file has the 'D' (can delete) within its group of permissions
*/
val hasDeletePermission: Boolean
get() = permissions?.contains(char = 'D', ignoreCase = true) ?: false

/**
* @return 'True' if the file has the 'N' (can rename) within its group of permissions
*/
val hasRenamePermission: Boolean
get() = permissions?.contains(char = 'N', ignoreCase = true) ?: false

/**
* @return 'True' if the file has the 'V' (can move) within its group of permissions
*/
val hasMovePermission: Boolean
get() = permissions?.contains(char = 'V', ignoreCase = true) ?: false

/**
* @return 'True' if the file has the 'C' (can add file) within its group of permissions
*/
Expand All @@ -117,6 +141,12 @@ data class OCFile(
val hasAddSubdirectoriesPermission: Boolean
get() = permissions?.contains(char = 'K', ignoreCase = true) ?: false

/**
* @return 'True' if the file has the 'R' (can reshare) within its group of permissions
*/
val hasResharePermission: Boolean
get() = permissions?.contains(char = 'R', ignoreCase = true) ?: false

/**
* get remote path of parent file
* @return remote path
Expand Down