Signed-off-by: tobiasKaminsky <tobias@kaminsky.me>
This commit is contained in:
tobiasKaminsky 2020-09-08 12:10:58 +02:00
parent 3262461100
commit d6d0c5939c
No known key found for this signature in database
GPG key ID: 0E00D4D47D0C5AF7
14 changed files with 454 additions and 181 deletions

View file

@ -97,7 +97,7 @@ public class FileDisplayActivityIT extends AbstractOnServerIT {
"users",
false,
"",
OCShare.DEFAULT_PERMISSION)
OCShare.NO_PERMISSION)
.execute(client).isSuccess());
// share folder to circle

View file

@ -31,6 +31,13 @@ import com.owncloud.android.AbstractIT
import com.owncloud.android.R
import com.owncloud.android.datamodel.OCFile
import com.owncloud.android.lib.resources.shares.OCShare
import com.owncloud.android.lib.resources.shares.OCShare.CREATE_PERMISSION_FLAG
import com.owncloud.android.lib.resources.shares.OCShare.DELETE_PERMISSION_FLAG
import com.owncloud.android.lib.resources.shares.OCShare.MAXIMUM_PERMISSIONS_FOR_FILE
import com.owncloud.android.lib.resources.shares.OCShare.MAXIMUM_PERMISSIONS_FOR_FOLDER
import com.owncloud.android.lib.resources.shares.OCShare.NO_PERMISSION
import com.owncloud.android.lib.resources.shares.OCShare.READ_PERMISSION_FLAG
import com.owncloud.android.lib.resources.shares.OCShare.SHARE_PERMISSION_FLAG
import com.owncloud.android.lib.resources.shares.ShareType
import com.owncloud.android.utils.ScreenshotTest
import org.junit.After
@ -166,7 +173,8 @@ class FileDetailSharingFragmentIT : AbstractIT() {
}
@Test
fun publicLink_optionMenu() {
// public link and email are handled the same way
fun publicLink_optionMenu_Folder() {
val sut = FileDetailSharingFragment.newInstance(file, user)
activity.addFragment(sut)
shortSleep()
@ -178,7 +186,7 @@ class FileDetailSharingFragmentIT : AbstractIT() {
val publicShare = OCShare().apply {
isFolder = true
shareType = ShareType.PUBLIC_LINK
permissions = OCShare.READ_PERMISSION_FLAG
permissions = 17
}
sut.prepareLinkOptionsMenu(popup.menu, publicShare)
@ -193,22 +201,24 @@ class FileDetailSharingFragmentIT : AbstractIT() {
assertTrue(popup.menu.findItem(R.id.action_unshare).isVisible)
assertTrue(popup.menu.findItem(R.id.action_add_another_public_share_link).isVisible)
// read-only
assertTrue(popup.menu.findItem(R.id.link_share_read_only).isChecked)
assertFalse(popup.menu.findItem(R.id.link_share_allow_upload_and_editing).isChecked)
assertFalse(popup.menu.findItem(R.id.link_share_file_drop).isChecked)
// upload and editing
publicShare.permissions = OCShare.MAXIMUM_PERMISSIONS_FOR_FOLDER
sut.prepareLinkOptionsMenu(popup.menu, publicShare)
assertFalse(popup.menu.findItem(R.id.link_share_read_only).isChecked)
assertTrue(popup.menu.findItem(R.id.link_share_allow_upload_and_editing).isChecked)
assertFalse(popup.menu.findItem(R.id.link_share_file_drop).isChecked)
// TODO
// publicShare.permissions = OCShare.MAXIMUM_PERMISSIONS_FOR_FOLDER
// sut.prepareLinkOptionsMenu(popup.menu, publicShare)
// assertFalse(popup.menu.findItem(R.id.link_share_read_only).isChecked)
// assertFalse(popup.menu.findItem(R.id.link_share_allow_upload_and_editing).isChecked)
// assertTrue(popup.menu.findItem(R.id.link_share_file_drop).isChecked)
// file drop
publicShare.permissions = 4
sut.prepareLinkOptionsMenu(popup.menu, publicShare)
assertFalse(popup.menu.findItem(R.id.link_share_read_only).isChecked)
assertFalse(popup.menu.findItem(R.id.link_share_allow_upload_and_editing).isChecked)
assertTrue(popup.menu.findItem(R.id.link_share_file_drop).isChecked)
// password protection
publicShare.shareWith = "someValue"
@ -230,11 +240,10 @@ class FileDetailSharingFragmentIT : AbstractIT() {
sut.prepareLinkOptionsMenu(popup.menu, publicShare)
assertFalse(popup.menu.findItem(R.id.action_hide_file_download).isChecked)
// TODO expires
// publicShare.expirationDate = 1582019340000
// sut.prepareLinkOptionsMenu(popup.menu, publicShare)
// assertTrue(popup.menu.findItem(R.id.action_share_expiration_date).title.startsWith(
// targetContext.getString(R.string.share_expiration_date_label)))
publicShare.expirationDate = 1582019340000
sut.prepareLinkOptionsMenu(popup.menu, publicShare)
assertTrue(popup.menu.findItem(R.id.action_share_expiration_date).title.startsWith(
targetContext.getString(R.string.share_expiration_date_label).split(" ")[0]))
publicShare.expirationDate = 0
sut.prepareLinkOptionsMenu(popup.menu, publicShare)
@ -261,9 +270,11 @@ class FileDetailSharingFragmentIT : AbstractIT() {
assertTrue(popup.menu.findItem(R.id.allow_editing).isVisible)
// allow editing
publicShare.permissions = 17 // from server
sut.prepareLinkOptionsMenu(popup.menu, publicShare)
assertFalse(popup.menu.findItem(R.id.allow_editing).isChecked)
publicShare.permissions = OCShare.UPDATE_PERMISSION_FLAG
publicShare.permissions = 19 // from server
sut.prepareLinkOptionsMenu(popup.menu, publicShare)
assertTrue(popup.menu.findItem(R.id.allow_editing).isChecked)
@ -278,13 +289,14 @@ class FileDetailSharingFragmentIT : AbstractIT() {
// password protection
publicShare.isPasswordProtected = true
publicShare.shareWith = "someValue"
sut.prepareLinkOptionsMenu(popup.menu, publicShare)
assertTrue(popup.menu.findItem(R.id.action_password).title ==
targetContext.getString(R.string.share_password_title))
publicShare.isPasswordProtected = false
publicShare.shareWith = ""
sut.prepareLinkOptionsMenu(popup.menu, publicShare)
assertFalse(popup.menu.findItem(R.id.action_password).isChecked)
assertTrue(popup.menu.findItem(R.id.action_password).title ==
targetContext.getString(R.string.share_no_password_title))
@ -292,15 +304,291 @@ class FileDetailSharingFragmentIT : AbstractIT() {
publicShare.expirationDate = 1582019340
sut.prepareLinkOptionsMenu(popup.menu, publicShare)
assertTrue(popup.menu.findItem(R.id.action_share_expiration_date).title.startsWith(
targetContext.getString(R.string.share_expiration_date_label)))
targetContext.getString(R.string.share_expiration_date_label).split(" ")[0]))
publicShare.expirationDate = 0
sut.prepareLinkOptionsMenu(popup.menu, publicShare)
assertTrue(popup.menu.findItem(R.id.action_share_expiration_date).title ==
targetContext.getString(R.string.share_no_expiration_date_label))
}
@Test
// public link and email are handled the same way
fun publicLink_optionMenu_File() {
val sut = FileDetailSharingFragment.newInstance(file, user)
activity.addFragment(sut)
shortSleep()
sut.refreshCapabilitiesFromDB()
val overflowMenuShareLink = ImageView(targetContext)
val popup = PopupMenu(targetContext, overflowMenuShareLink)
popup.inflate(R.menu.fragment_file_detail_sharing_public_link)
val publicShare = OCShare().apply {
isFolder = false
shareType = ShareType.PUBLIC_LINK
permissions = 17
}
sut.prepareLinkOptionsMenu(popup.menu, publicShare)
// check if items are visible
assertTrue(popup.menu.findItem(R.id.action_hide_file_download).isVisible)
assertTrue(popup.menu.findItem(R.id.action_password).isVisible)
assertTrue(popup.menu.findItem(R.id.action_share_expiration_date).isVisible)
assertTrue(popup.menu.findItem(R.id.action_share_send_link).isVisible)
assertTrue(popup.menu.findItem(R.id.action_share_send_note).isVisible)
assertTrue(popup.menu.findItem(R.id.action_edit_label).isVisible)
assertTrue(popup.menu.findItem(R.id.action_unshare).isVisible)
assertTrue(popup.menu.findItem(R.id.action_add_another_public_share_link).isVisible)
assertFalse(popup.menu.findItem(R.id.link_share_read_only).isVisible)
assertFalse(popup.menu.findItem(R.id.link_share_allow_upload_and_editing).isVisible)
assertFalse(popup.menu.findItem(R.id.link_share_file_drop).isVisible)
assertTrue(popup.menu.findItem(R.id.allow_editing).isVisible)
// password protection
publicShare.shareWith = "someValue"
sut.prepareLinkOptionsMenu(popup.menu, publicShare)
assertTrue(popup.menu.findItem(R.id.action_password).title ==
targetContext.getString(R.string.share_password_title))
publicShare.shareWith = ""
sut.prepareLinkOptionsMenu(popup.menu, publicShare)
assertTrue(popup.menu.findItem(R.id.action_password).title ==
targetContext.getString(R.string.share_no_password_title))
// hide download
publicShare.isHideFileDownload = true
sut.prepareLinkOptionsMenu(popup.menu, publicShare)
assertTrue(popup.menu.findItem(R.id.action_hide_file_download).isChecked)
publicShare.isHideFileDownload = false
sut.prepareLinkOptionsMenu(popup.menu, publicShare)
assertFalse(popup.menu.findItem(R.id.action_hide_file_download).isChecked)
// expiration date
publicShare.expirationDate = 1582019340000
sut.prepareLinkOptionsMenu(popup.menu, publicShare)
assertTrue(popup.menu.findItem(R.id.action_share_expiration_date).title.startsWith(
targetContext.getString(R.string.share_expiration_date_label).split(" ")[0]))
publicShare.expirationDate = 0
sut.prepareLinkOptionsMenu(popup.menu, publicShare)
assertTrue(popup.menu.findItem(R.id.action_share_expiration_date).title ==
targetContext.getString(R.string.share_no_expiration_date_label))
// TODO check all options
// scenarios: public link, email, …, both for file/folder
publicShare.isFolder = false
publicShare.permissions = OCShare.READ_PERMISSION_FLAG
sut.prepareLinkOptionsMenu(popup.menu, publicShare)
// allow editing
publicShare.permissions = 17 // from server
assertFalse(popup.menu.findItem(R.id.allow_editing).isChecked)
publicShare.permissions = 19 // from server
sut.prepareLinkOptionsMenu(popup.menu, publicShare)
assertTrue(popup.menu.findItem(R.id.allow_editing).isChecked)
}
@Test
// also applies for
// group
// conversation
// circle
// federated share
fun user_optionMenu_File() {
val sut = FileDetailSharingFragment.newInstance(file, user)
activity.addFragment(sut)
shortSleep()
sut.refreshCapabilitiesFromDB()
val overflowMenuShareLink = ImageView(targetContext)
val popup = PopupMenu(targetContext, overflowMenuShareLink)
popup.inflate(R.menu.item_user_sharing_settings)
val userShare = OCShare().apply {
isFolder = false
shareType = ShareType.USER
permissions = 17
}
sut.prepareUserOptionsMenu(popup.menu, userShare)
assertFalse(popup.menu.findItem(R.id.allow_creating).isVisible)
assertFalse(popup.menu.findItem(R.id.allow_deleting).isVisible)
// allow editing
userShare.permissions = 17 // from server
assertFalse(popup.menu.findItem(R.id.allow_editing).isChecked)
userShare.permissions = 19 // from server
sut.prepareUserOptionsMenu(popup.menu, userShare)
assertTrue(popup.menu.findItem(R.id.allow_editing).isChecked)
// allow reshare
userShare.permissions = 1 // from server
sut.prepareUserOptionsMenu(popup.menu, userShare)
assertFalse(popup.menu.findItem(R.id.allow_resharing).isChecked)
userShare.permissions = 17 // from server
sut.prepareUserOptionsMenu(popup.menu, userShare)
assertTrue(popup.menu.findItem(R.id.allow_resharing).isChecked)
// set expiration date
userShare.expirationDate = 1582019340000
sut.prepareUserOptionsMenu(popup.menu, userShare)
assertTrue(popup.menu.findItem(R.id.action_expiration_date).title.startsWith(
targetContext.getString(R.string.share_expiration_date_label).split(" ")[0]))
userShare.expirationDate = 0
sut.prepareUserOptionsMenu(popup.menu, userShare)
assertTrue(popup.menu.findItem(R.id.action_expiration_date).title ==
targetContext.getString(R.string.share_no_expiration_date_label))
// note
assertTrue(popup.menu.findItem(R.id.action_share_send_note).isVisible)
}
@Test
// also applies for
// group
// conversation
// circle
// federated share
fun user_optionMenu_Folder() {
val sut = FileDetailSharingFragment.newInstance(file, user)
activity.addFragment(sut)
shortSleep()
sut.refreshCapabilitiesFromDB()
val overflowMenuShareLink = ImageView(targetContext)
val popup = PopupMenu(targetContext, overflowMenuShareLink)
popup.inflate(R.menu.item_user_sharing_settings)
val userShare = OCShare().apply {
isFolder = true
shareType = ShareType.USER
permissions = 17
}
sut.prepareUserOptionsMenu(popup.menu, userShare)
assertTrue(popup.menu.findItem(R.id.allow_creating).isVisible)
assertTrue(popup.menu.findItem(R.id.allow_deleting).isVisible)
// allow editing
userShare.permissions = 17 // from server
assertFalse(popup.menu.findItem(R.id.allow_editing).isChecked)
userShare.permissions = 19 // from server
sut.prepareUserOptionsMenu(popup.menu, userShare)
assertTrue(popup.menu.findItem(R.id.allow_editing).isChecked)
// allow reshare
userShare.permissions = 1 // from server
sut.prepareUserOptionsMenu(popup.menu, userShare)
assertFalse(popup.menu.findItem(R.id.allow_resharing).isChecked)
userShare.permissions = 17 // from server
sut.prepareUserOptionsMenu(popup.menu, userShare)
assertTrue(popup.menu.findItem(R.id.allow_resharing).isChecked)
// set expiration date
userShare.expirationDate = 1582019340000
sut.prepareUserOptionsMenu(popup.menu, userShare)
assertTrue(popup.menu.findItem(R.id.action_expiration_date).title.startsWith(
targetContext.getString(R.string.share_expiration_date_label).split(" ")[0]))
userShare.expirationDate = 0
sut.prepareUserOptionsMenu(popup.menu, userShare)
assertTrue(popup.menu.findItem(R.id.action_expiration_date).title ==
targetContext.getString(R.string.share_no_expiration_date_label))
// note
assertTrue(popup.menu.findItem(R.id.action_share_send_note).isVisible)
}
@Test
fun testUploadAndEditingSharePermissions() {
val sut = FileDetailSharingFragment()
val share = OCShare().apply {
permissions = MAXIMUM_PERMISSIONS_FOR_FOLDER
}
assertTrue(sut.isUploadAndEditingAllowed(share))
share.permissions = NO_PERMISSION
assertFalse(sut.isUploadAndEditingAllowed(share))
share.permissions = READ_PERMISSION_FLAG
assertFalse(sut.isUploadAndEditingAllowed(share))
share.permissions = CREATE_PERMISSION_FLAG
assertFalse(sut.isUploadAndEditingAllowed(share))
share.permissions = DELETE_PERMISSION_FLAG
assertFalse(sut.isUploadAndEditingAllowed(share))
share.permissions = SHARE_PERMISSION_FLAG
assertFalse(sut.isUploadAndEditingAllowed(share))
}
@Test
fun testReadOnlySharePermissions() {
val sut = FileDetailSharingFragment()
val share = OCShare().apply {
permissions = 17
}
assertTrue(sut.isReadOnly(share))
share.permissions = NO_PERMISSION
assertFalse(sut.isReadOnly(share))
share.permissions = READ_PERMISSION_FLAG
assertTrue(sut.isReadOnly(share))
share.permissions = CREATE_PERMISSION_FLAG
assertFalse(sut.isReadOnly(share))
share.permissions = DELETE_PERMISSION_FLAG
assertFalse(sut.isReadOnly(share))
share.permissions = SHARE_PERMISSION_FLAG
assertFalse(sut.isReadOnly(share))
share.permissions = MAXIMUM_PERMISSIONS_FOR_FOLDER
assertFalse(sut.isReadOnly(share))
share.permissions = MAXIMUM_PERMISSIONS_FOR_FILE
assertFalse(sut.isReadOnly(share))
}
@Test
fun testFileDropSharePermissions() {
val sut = FileDetailSharingFragment()
val share = OCShare().apply {
permissions = 4
}
assertTrue(sut.isFileDrop(share))
share.permissions = NO_PERMISSION
assertFalse(sut.isFileDrop(share))
share.permissions = READ_PERMISSION_FLAG
assertFalse(sut.isFileDrop(share))
share.permissions = CREATE_PERMISSION_FLAG
assertTrue(sut.isFileDrop(share))
share.permissions = DELETE_PERMISSION_FLAG
assertFalse(sut.isFileDrop(share))
share.permissions = SHARE_PERMISSION_FLAG
assertFalse(sut.isFileDrop(share))
share.permissions = MAXIMUM_PERMISSIONS_FOR_FOLDER
assertFalse(sut.isFileDrop(share))
share.permissions = MAXIMUM_PERMISSIONS_FOR_FILE
assertFalse(sut.isFileDrop(share))
}
@After

View file

@ -224,7 +224,7 @@ class OCFileListFragmentIT : AbstractOnServerIT() {
"users",
false,
"",
OCShare.DEFAULT_PERMISSION
OCShare.NO_PERMISSION
)
.execute(client)
.isSuccess

View file

@ -52,7 +52,7 @@ public class CreateShareViaLinkOperation extends SyncOperation {
"",
false,
password,
OCShare.DEFAULT_PERMISSION);
OCShare.NO_PERMISSION);
createOp.setGetShareDetails(true);
RemoteOperationResult result = createOp.execute(client);

View file

@ -56,14 +56,13 @@ public class UpdateShareViaLinkOperation extends SyncOperation {
updateOp.setPassword(password);
updateOp.setExpirationDate(expirationDateInMillis);
updateOp.setHideFileDownload(hideFileDownload);
//updateOp.setVideoVerification(videoVerification);
updateOp.setLabel(label);
if (publicShare.isFolder()) {
updateOp.setPublicUploadOnFolder(publicUpload);
} else {
updateOp.setPublicUploadOnFile(publicUpload);
}
// if (publicShare.isFolder()) {
// updateOp.setPublicUploadOnFolder(publicUpload);
// } else {
// updateOp.setPublicUploadOnFile(publicUpload);
// }
RemoteOperationResult result = updateOp.execute(client);

View file

@ -746,7 +746,6 @@ public abstract class FileActivity extends DrawerActivity
if (result.isSuccess()) {
if (sharingFragment != null) {
sharingFragment.refreshSharesFromDB();
sharingFragment.onUpdateShareInformation(result, getFile());
}
} else {
@ -761,7 +760,6 @@ public abstract class FileActivity extends DrawerActivity
if (result.isSuccess()) {
updateFileFromDB();
if (sharingFragment != null) {
sharingFragment.refreshSharesFromDB();
sharingFragment.onUpdateShareInformation(result, getFile());
}
} else if (sharingFragment != null && sharingFragment.getView() != null) {
@ -807,7 +805,6 @@ public abstract class FileActivity extends DrawerActivity
copyAndShareFileLink(this, file, link);
if (sharingFragment != null) {
sharingFragment.refreshSharesFromDB();
sharingFragment.onUpdateShareInformation(result, getFile());
}
} else {

View file

@ -145,7 +145,6 @@ public class ShareActivity extends FileActivity {
if (shareFileFragment != null
&& shareFileFragment.isAdded()) { // only if added to the view hierarchy!!
shareFileFragment.refreshCapabilitiesFromDB();
//shareFileFragment.refrefreshUsersOrGroupsListFromDB();
shareFileFragment.refreshSharesFromDB();
}
}

View file

@ -64,10 +64,6 @@ class ShareViewHolder extends RecyclerView.ViewHolder {
name = context.getString(R.string.share_group_clarification, name);
setImage(binding.icon, share.getSharedWithDisplayName(), R.drawable.ic_group);
break;
case EMAIL:
name = context.getString(R.string.share_email_clarification, name);
setImage(binding.icon, share.getSharedWithDisplayName(), R.drawable.ic_email);
break;
case ROOM:
name = context.getString(R.string.share_room_clarification, name);
setImage(binding.icon, share.getSharedWithDisplayName(), R.drawable.ic_chat_bubble);

View file

@ -27,13 +27,12 @@ import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.TextView;
import com.owncloud.android.R;
import com.owncloud.android.databinding.PasswordDialogBinding;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.lib.resources.shares.OCShare;
import com.owncloud.android.ui.activity.FileActivity;
@ -41,7 +40,6 @@ import com.owncloud.android.utils.DisplayUtils;
import com.owncloud.android.utils.ThemeUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
@ -58,6 +56,7 @@ public class SharePasswordDialogFragment extends DialogFragment implements Dialo
private static final String ARG_ASK_FOR_PASSWORD = "ASK_FOR_PASSWORD";
public static final String PASSWORD_FRAGMENT = "PASSWORD_FRAGMENT";
private PasswordDialogBinding binding;
private OCFile file;
private OCShare share;
private boolean createShare;
@ -122,12 +121,6 @@ public class SharePasswordDialogFragment extends DialogFragment implements Dialo
return frag;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return super.onCreateView(inflater, container, savedInstanceState);
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
@ -137,17 +130,18 @@ public class SharePasswordDialogFragment extends DialogFragment implements Dialo
askForPassword = getArguments().getBoolean(ARG_ASK_FOR_PASSWORD, false);
// Inflate the layout for the dialog
LayoutInflater inflater = getActivity().getLayoutInflater();
View v = inflater.inflate(R.layout.password_dialog, null);
LayoutInflater inflater = requireActivity().getLayoutInflater();
binding = PasswordDialogBinding.inflate(inflater, null, false);
View view = binding.getRoot();
// Setup layout
EditText inputText = v.findViewById(R.id.share_password);
inputText.getBackground().setColorFilter(
ThemeUtils.primaryAccentColor(getContext()),
PorterDuff.Mode.SRC_ATOP
);
EditText inputText = binding.sharePassword;
inputText.setHighlightColor(ThemeUtils.primaryColor(getActivity()));
inputText.setText("");
ThemeUtils.themeEditText(getContext(), inputText, false);
inputText.requestFocus();
inputText.getBackground().setColorFilter(ThemeUtils.primaryAccentColor(getContext()),
PorterDuff.Mode.SRC_ATOP);
int title;
if (askForPassword) {
@ -157,10 +151,9 @@ public class SharePasswordDialogFragment extends DialogFragment implements Dialo
}
// Build the dialog
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(),
R.style.Theme_ownCloud_Dialog_NoButtonBarStyle);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(v)
builder.setView(view)
.setPositiveButton(R.string.common_ok, this)
.setNegativeButton(R.string.common_cancel, this)
.setNeutralButton(R.string.common_delete, this)
@ -178,11 +171,10 @@ public class SharePasswordDialogFragment extends DialogFragment implements Dialo
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == AlertDialog.BUTTON_POSITIVE) {
String password = ((TextView) (getDialog().findViewById(R.id.share_password))).getText().toString();
String password = binding.sharePassword.getText().toString();
if (!askForPassword && TextUtils.isEmpty(password)) {
DisplayUtils.showSnackMessage(getActivity().findViewById(android.R.id.content),
R.string.share_link_empty_password);
DisplayUtils.showSnackMessage(binding.getRoot(), R.string.share_link_empty_password);
return;
}
@ -217,4 +209,10 @@ public class SharePasswordDialogFragment extends DialogFragment implements Dialo
private void setPassword(OCShare share, String password) {
((FileActivity) getActivity()).getFileOperationsHelper().setPasswordToShare(share, password);
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}

View file

@ -80,7 +80,12 @@ import androidx.appcompat.widget.PopupMenu;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import static com.owncloud.android.lib.resources.shares.OCShare.CREATE_PERMISSION_FLAG;
import static com.owncloud.android.lib.resources.shares.OCShare.MAXIMUM_PERMISSIONS_FOR_FILE;
import static com.owncloud.android.lib.resources.shares.OCShare.MAXIMUM_PERMISSIONS_FOR_FOLDER;
import static com.owncloud.android.lib.resources.shares.OCShare.NO_PERMISSION;
import static com.owncloud.android.lib.resources.shares.OCShare.READ_PERMISSION_FLAG;
import static com.owncloud.android.lib.resources.shares.OCShare.SHARE_PERMISSION_FLAG;
public class FileDetailSharingFragment extends Fragment implements ShareeListAdapterListener,
DisplayUtils.AvatarGenerationListener,
@ -197,7 +202,6 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
ThemeUtils.themeSearchView(binding.searchView, requireContext());
if (file.canReshare()) {
refreshSharesFromDB();
binding.searchView.setQueryHint(getResources().getString(R.string.share_search));
} else {
binding.searchView.setQueryHint(getResources().getString(R.string.reshare_not_allowed));
@ -314,32 +318,23 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
* @param menu the menu of the sharee/shared file
* @param share the shared file
*/
private void prepareUserOptionsMenu(Menu menu, OCShare share) {
@VisibleForTesting
public void prepareUserOptionsMenu(Menu menu, OCShare share) {
MenuItem allowEditingItem = menu.findItem(R.id.allow_editing);
MenuItem allowCreatingItem = menu.findItem(R.id.allow_creating);
MenuItem allowDeletingItem = menu.findItem(R.id.allow_deleting);
MenuItem hideFileListingItem = menu.findItem(R.id.action_hide_file_listing);
MenuItem passwordItem = menu.findItem(R.id.action_password);
MenuItem expirationDateItem = menu.findItem(R.id.action_expiration_date);
MenuItem reshareItem = menu.findItem(R.id.allow_resharing);
MenuItem sendNoteItem = menu.findItem(R.id.action_share_send_note);
allowEditingItem.setChecked(canEdit(share));
if (isReshareForbidden(share)) {
reshareItem.setVisible(false);
}
reshareItem.setChecked(canReshare(share));
if (share.getShareType() == ShareType.EMAIL) {
SharingMenuHelper.setupHideFileListingMenuItem(hideFileListingItem,
file.isFolder(),
canEdit(share),
share.getPermissions());
SharingMenuHelper.setupPasswordMenuItem(passwordItem, share.isPasswordProtected());
reshareItem.setVisible(false);
allowCreatingItem.setVisible(false);
allowDeletingItem.setVisible(false);
} else {
if (file.isFolder() && isEditOptionsAvailable(share)) {
if (file.isFolder() || share.isFolder()) {
allowCreatingItem.setChecked(canCreate(share));
allowDeletingItem.setChecked(canDelete(share));
} else {
@ -347,13 +342,9 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
allowDeletingItem.setVisible(false);
}
hideFileListingItem.setVisible(false);
passwordItem.setVisible(false);
if (!capabilities.getVersion().isNewerOrEqual(OwnCloudVersion.nextcloud_18)) {
expirationDateItem.setVisible(false);
}
}
SharingMenuHelper.setupExpirationDateMenuItem(menu.findItem(R.id.action_expiration_date),
share.getExpirationDate(),
@ -386,23 +377,28 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
menu.findItem(R.id.allow_editing).setVisible(false);
// read only / allow upload and editing / file drop
MenuItem readOnly = menu.findItem(R.id.link_share_read_only);
MenuItem uploadAndEditing = menu.findItem(R.id.link_share_allow_upload_and_editing);
MenuItem fileDrop = menu.findItem(R.id.link_share_file_drop);
if ((publicShare.getPermissions() & MAXIMUM_PERMISSIONS_FOR_FOLDER) == MAXIMUM_PERMISSIONS_FOR_FOLDER) {
uploadAndEditing.setChecked(true);
} else if ((publicShare.getPermissions() & OCShare.READ_PERMISSION_FLAG) == 1) {
readOnly.setChecked(true);
if ((isUploadAndEditingAllowed(publicShare))) {
menu.findItem(R.id.link_share_allow_upload_and_editing).setChecked(true);
} else if (isFileDrop(publicShare)) {
menu.findItem(R.id.link_share_file_drop).setChecked(true);
} else if (isReadOnly(publicShare)) {
menu.findItem(R.id.link_share_read_only).setChecked(true);
}
} else {
menu.setGroupVisible(R.id.folder_permission, false);
menu.findItem(R.id.allow_editing).setVisible(true);
if (publicShare.getPermissions() > PERMISSION_EDITING_ALLOWED) {
menu.findItem(R.id.allow_editing).setChecked(true);
} else {
menu.findItem(R.id.allow_editing).setChecked(false);
}
}
Resources res = requireContext().getResources();
SharingMenuHelper.setupHideFileDownload(menu.findItem(R.id.action_hide_file_download),
publicShare.isHideFileDownload(),
isFileDrop(publicShare),
capabilities);
SharingMenuHelper.setupPasswordMenuItem(menu.findItem(R.id.action_password),
@ -415,10 +411,36 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
menu.findItem(R.id.action_share_send_note).setVisible(capabilities.getVersion().isNoteOnShareSupported());
}
private boolean userOptionsItemSelected(Menu menu,
MenuItem item,
OCShare share) {
@VisibleForTesting
public boolean isUploadAndEditingAllowed(OCShare share) {
if (share.getPermissions() == NO_PERMISSION) {
return false;
}
return (share.getPermissions() & MAXIMUM_PERMISSIONS_FOR_FOLDER) == MAXIMUM_PERMISSIONS_FOR_FOLDER;
}
@VisibleForTesting
public boolean isReadOnly(OCShare share) {
if (share.getPermissions() == NO_PERMISSION) {
return false;
}
return (share.getPermissions() & ~SHARE_PERMISSION_FLAG) == READ_PERMISSION_FLAG;
}
@VisibleForTesting
public boolean isFileDrop(OCShare share) {
if (share.getPermissions() == NO_PERMISSION) {
return false;
}
return (share.getPermissions() & ~SHARE_PERMISSION_FLAG) == CREATE_PERMISSION_FLAG;
}
private boolean userOptionsItemSelected(Menu menu, MenuItem item, OCShare share) {
switch (item.getItemId()) {
case R.id.allow_editing:
case R.id.allow_creating:
case R.id.allow_deleting:
case R.id.allow_resharing: {
@ -432,11 +454,13 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
}
case R.id.action_unshare: {
unshareWith(share);
((ShareeListAdapter) binding.sharesList.getAdapter()).remove(share);
ShareeListAdapter adapter = ((ShareeListAdapter) binding.sharesList.getAdapter());
if (adapter == null) {
DisplayUtils.showSnackMessage(getView(), getString(R.string.failed_update_ui));
return true;
}
case R.id.action_password: {
requestPasswordForShare(share, capabilities.getFilesSharingPublicAskForOptionalPassword().isTrue());
adapter.remove(share);
return true;
}
case R.id.action_expiration_date: {
@ -457,26 +481,32 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
public boolean linkOptionsItemSelected(MenuItem item, OCShare publicShare) {
switch (item.getItemId()) {
// case R.id.action_allow_editing:
// if (file.isSharedViaLink()) {
// item.setChecked(!item.isChecked());
// fileOperationsHelper.setUploadPermissionsToPublicShare(publicShare, item.isChecked());
// }
// return true;
case R.id.action_hide_file_listing: {
item.setChecked(!item.isChecked());
fileOperationsHelper.setHideFileListingPermissionsToPublicShare(publicShare, item.isChecked());
case R.id.link_share_read_only:
item.setChecked(true);
fileOperationsHelper.setPermissionsToShare(publicShare, READ_PERMISSION_FLAG);
return true;
case R.id.link_share_allow_upload_and_editing:
item.setChecked(true);
if (publicShare.isFolder()) {
fileOperationsHelper.setPermissionsToShare(publicShare, MAXIMUM_PERMISSIONS_FOR_FOLDER);
} else {
fileOperationsHelper.setPermissionsToShare(publicShare, MAXIMUM_PERMISSIONS_FOR_FILE);
}
return true;
case R.id.link_share_file_drop: {
item.setChecked(true);
fileOperationsHelper.setPermissionsToShare(publicShare, CREATE_PERMISSION_FLAG);
return true;
}
case R.id.allow_editing:
if (file.isSharedViaLink()) {
item.setChecked(!item.isChecked());
fileOperationsHelper.setUploadPermissionsToPublicShare(publicShare, item.isChecked());
}
return true;
case R.id.action_hide_file_download:
item.setChecked(!item.isChecked());
fileOperationsHelper.setHideFileDownloadPermissionsToPublicShare(publicShare, item.isChecked());
return true;
case R.id.action_edit_label:
RenamePublicShareDialogFragment renameDialog = RenamePublicShareDialogFragment.newInstance(publicShare);
renameDialog.show(fileActivity.getSupportFragmentManager(),
RenamePublicShareDialogFragment.RENAME_PUBLIC_SHARE_FRAGMENT);
return true;
case R.id.action_password: {
requestPasswordForShare(publicShare,
@ -502,12 +532,17 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
NoteDialogFragment noteDialog = NoteDialogFragment.newInstance(publicShare);
noteDialog.show(fileActivity.getSupportFragmentManager(), NoteDialogFragment.NOTE_FRAGMENT);
return true;
case R.id.action_add_another_public_share_link:
createPublicShareLink();
case R.id.action_edit_label:
RenamePublicShareDialogFragment renameDialog = RenamePublicShareDialogFragment.newInstance(publicShare);
renameDialog.show(fileActivity.getSupportFragmentManager(),
RenamePublicShareDialogFragment.RENAME_PUBLIC_SHARE_FRAGMENT);
return true;
case R.id.action_unshare:
fileOperationsHelper.unshareShare(file, publicShare);
return true;
case R.id.action_add_another_public_share_link:
createPublicShareLink();
return true;
default:
return super.onOptionsItemSelected(item);
}
@ -533,6 +568,7 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
* Get {@link OCShare} instance from DB and updates the UI.
*/
private void refreshUiFromDB() {
refreshSharesFromDB();
// Updates UI with new state
setupView();
}
@ -594,8 +630,12 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
* Takes into account server capabilities before reading database.
*/
public void refreshSharesFromDB() {
// TODO check if this is not called too often
ShareeListAdapter adapter = (ShareeListAdapter) binding.sharesList.getAdapter();
if (adapter == null) {
DisplayUtils.showSnackMessage(getView(), getString(R.string.could_not_retrieve_shares));
return;
}
adapter.getShares().clear();
// to show share with users/groups info
@ -657,11 +697,6 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
(capabilities != null && capabilities.getFilesSharingResharing().isFalse());
}
private boolean isEditOptionsAvailable(OCShare share) {
return !ShareType.FEDERATED.equals(share.getShareType());
}
private boolean canEdit(OCShare share) {
return (share.getPermissions() &
(OCShare.CREATE_PERMISSION_FLAG | OCShare.UPDATE_PERMISSION_FLAG | OCShare.DELETE_PERMISSION_FLAG)) > 0;
@ -671,32 +706,10 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
return (share.getPermissions() & OCShare.CREATE_PERMISSION_FLAG) > 0;
}
private boolean canUpdate(OCShare share) {
return (share.getPermissions() & OCShare.UPDATE_PERMISSION_FLAG) > 0;
}
private boolean canDelete(OCShare share) {
return (share.getPermissions() & OCShare.DELETE_PERMISSION_FLAG) > 0;
}
// private void allowEditClick(AppCompatCheckBox checkBox, @NonNull OCShare share) {
// if (!share.isFolder()) {
// share.setPermissions(updatePermissionsToShare(share,
// canReshare(share),
// checkBox.isChecked(),
// false,
// false,
// false));
// } else {
// share.setPermissions(updatePermissionsToShare(share,
// canReshare(share),
// checkBox.isChecked(),
// checkBox.isChecked(),
// checkBox.isChecked(),
// checkBox.isChecked()));
// }
// }
private boolean canReshare(OCShare share) {
return (share.getPermissions() & OCShare.SHARE_PERMISSION_FLAG) > 0;
}

View file

@ -65,11 +65,15 @@ public final class SharingMenuHelper {
/**
* Sets checked/visibility state on the given {@link MenuItem} based on the given criteria.
*
* @param menuItem the {@link MenuItem} to be setup
* @param capabilities Capabilities of server to check if hide download is supported
*/
public static void setupHideFileDownload(MenuItem menuItem, boolean hideFileDownload, OCCapability capabilities) {
if (!capabilities.getVersion().isHideFileDownloadSupported()) {
public static void setupHideFileDownload(MenuItem menuItem,
boolean hideFileDownload,
boolean isFileDrop,
OCCapability capabilities) {
if (!capabilities.getVersion().isHideFileDownloadSupported() || isFileDrop) {
menuItem.setVisible(false);
} else {
menuItem.setVisible(true);

View file

@ -18,19 +18,11 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="clip_horizontal"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/TextInputLayout"
app:hintTextColor="@color/fg_inverse"
app:passwordToggleDrawable="@drawable/password_visibility_selector"
app:boxBackgroundColor="@color/bg_default"
app:boxStrokeColor="@color/bg_fallback_highlight">
android:padding="@dimen/standard_padding">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/share_password"
@ -39,11 +31,7 @@
android:ems="10"
android:hint="@string/hint_password"
android:inputType="textPassword"
android:layout_margin="@dimen/standard_margin"
android:autofillHints="password"
android:textColorHint="@color/bg_fallback_highlight">
</com.google.android.material.textfield.TextInputEditText>
</com.google.android.material.textfield.TextInputLayout>
android:textColorHint="@color/bg_fallback_highlight"></com.google.android.material.textfield.TextInputEditText>
</LinearLayout>

View file

@ -46,17 +46,6 @@
android:showAsAction="never"
android:title="@string/allow_resharing"
app:showAsAction="never" />
<item
android:id="@+id/action_hide_file_listing"
android:showAsAction="never"
android:title="@string/share_via_link_hide_file_listing_permission_label"
android:checkable="true"
app:showAsAction="never" />
<item
android:id="@+id/action_password"
android:showAsAction="never"
android:title="@string/share_via_link_menu_password_label"
app:showAsAction="never" />
<item
android:id="@+id/action_expiration_date"
android:showAsAction="never"

View file

@ -943,4 +943,6 @@
<string name="link_share_allow_upload_and_editing">Allow upload and editing</string>
<string name="link_share_file_drop">File drop (upload only)</string>
<string name="link_share_video_verification">Video verification</string>
<string name="could_not_retrieve_shares">Could not retrieve shares</string>
<string name="failed_update_ui">Failed to update UI</string>
</resources>