Skip to content

Commit

Permalink
Merge pull request #3997 from owncloud/spaces/file_permissions
Browse files Browse the repository at this point in the history
[SPACES] WebDAV permissions in files
  • Loading branch information
JuancaG05 authored Apr 3, 2023
2 parents 0d7e5d6 + 277ede3 commit ef3eefe
Show file tree
Hide file tree
Showing 11 changed files with 115 additions and 27 deletions.
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

0 comments on commit ef3eefe

Please sign in to comment.