diff --git a/scripts/analysis/findbugs-results.txt b/scripts/analysis/findbugs-results.txt index 9ec873d37d50..c8eb5888ce88 100644 --- a/scripts/analysis/findbugs-results.txt +++ b/scripts/analysis/findbugs-results.txt @@ -1 +1 @@ -438 \ No newline at end of file +438 diff --git a/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java b/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java index 30b94412fd8c..0fb9b3f8d5a4 100644 --- a/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java +++ b/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java @@ -1924,6 +1924,8 @@ public OCCapability saveCapabilities(OCCapability capability) { capability.getFilesSharingPublicEnabled().getValue()); cv.put(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_PASSWORD_ENFORCED, capability.getFilesSharingPublicPasswordEnforced().getValue()); + cv.put(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_ASK_FOR_OPTIONAL_PASSWORD, + capability.getFilesSharingPublicAskForOptionalPassword().getValue()); cv.put(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_ENABLED, capability.getFilesSharingPublicExpireDateEnabled().getValue()); cv.put(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_DAYS, @@ -2078,6 +2080,9 @@ private OCCapability createCapabilityInstance(Cursor c) { .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_ENABLED)))); capability.setFilesSharingPublicPasswordEnforced(CapabilityBooleanType.fromValue(c.getInt(c .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_PASSWORD_ENFORCED)))); + capability.setFilesSharingPublicAskForOptionalPassword( + CapabilityBooleanType.fromValue( + c.getInt(c.getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_ASK_FOR_OPTIONAL_PASSWORD)))); capability.setFilesSharingPublicExpireDateEnabled(CapabilityBooleanType.fromValue(c.getInt(c .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_ENABLED)))); capability.setFilesSharingPublicExpireDateDays(c.getInt(c diff --git a/src/main/java/com/owncloud/android/db/ProviderMeta.java b/src/main/java/com/owncloud/android/db/ProviderMeta.java index 7621a6ea1169..b291a1c3f4b3 100644 --- a/src/main/java/com/owncloud/android/db/ProviderMeta.java +++ b/src/main/java/com/owncloud/android/db/ProviderMeta.java @@ -31,7 +31,7 @@ */ public class ProviderMeta { public static final String DB_NAME = "filelist"; - public static final int DB_VERSION = 46; + public static final int DB_VERSION = 47; private ProviderMeta() { // No instance @@ -155,6 +155,8 @@ static public class ProviderTableMeta implements BaseColumns { public static final String CAPABILITIES_SHARING_API_ENABLED = "sharing_api_enabled"; public static final String CAPABILITIES_SHARING_PUBLIC_ENABLED = "sharing_public_enabled"; public static final String CAPABILITIES_SHARING_PUBLIC_PASSWORD_ENFORCED = "sharing_public_password_enforced"; + public static final String CAPABILITIES_SHARING_PUBLIC_ASK_FOR_OPTIONAL_PASSWORD = + "sharing_public_ask_for_optional_password"; public static final String CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_ENABLED = "sharing_public_expire_date_enabled"; public static final String CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_DAYS = diff --git a/src/main/java/com/owncloud/android/providers/FileContentProvider.java b/src/main/java/com/owncloud/android/providers/FileContentProvider.java index 86ae7efaa40d..008b0437290b 100644 --- a/src/main/java/com/owncloud/android/providers/FileContentProvider.java +++ b/src/main/java/com/owncloud/android/providers/FileContentProvider.java @@ -770,7 +770,8 @@ private void createCapabilitiesTable(SQLiteDatabase db) { + ProviderTableMeta.CAPABILITIES_RICHDOCUMENT_MIMETYPE_LIST + TEXT + ProviderTableMeta.CAPABILITIES_RICHDOCUMENT_DIRECT_EDITING + INTEGER + ProviderTableMeta.CAPABILITIES_RICHDOCUMENT_TEMPLATES + INTEGER - + ProviderTableMeta.CAPABILITIES_RICHDOCUMENT_OPTIONAL_MIMETYPE_LIST + " TEXT );"); + + ProviderTableMeta.CAPABILITIES_RICHDOCUMENT_OPTIONAL_MIMETYPE_LIST + TEXT + + ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_ASK_FOR_OPTIONAL_PASSWORD + " INTEGER );"); } private void createUploadsTable(SQLiteDatabase db) { @@ -1946,6 +1947,25 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { if (!upgraded) { Log_OC.i(SQL, String.format(Locale.ENGLISH, UPGRADE_VERSION_MSG, oldVersion, newVersion)); } + + if (oldVersion < 47 && newVersion >= 47) { + Log_OC.i(SQL, "Entering in the #47 add askForPassword to capability table"); + db.beginTransaction(); + try { + db.execSQL(ALTER_TABLE + ProviderTableMeta.CAPABILITIES_TABLE_NAME + + ADD_COLUMN + ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_ASK_FOR_OPTIONAL_PASSWORD + + " INTEGER "); + + upgraded = true; + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + } + } + + if (!upgraded) { + Log_OC.i(SQL, String.format(Locale.ENGLISH, UPGRADE_VERSION_MSG, oldVersion, newVersion)); + } } @Override diff --git a/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java b/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java index 53ce4114389b..2e0df3ffe7e7 100644 --- a/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java +++ b/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java @@ -2016,10 +2016,13 @@ private void onCreateShareViaLinkOperationFinish(CreateShareViaLinkOperation ope // Was tried without password, but not sure that it's optional. // Try with password before giving up; see also ShareFileFragment#OnShareViaLinkListener - if (fileDetailFragment != null - && fileDetailFragment.isAdded()) { // only if added to the view hierarchy!! + if (fileDetailFragment != null && fileDetailFragment.isAdded()) { // only if added to the view hierarchy - fileDetailFragment.getFileDetailSharingFragment().requestPasswordForShareViaLink(true); + fileDetailFragment + .getFileDetailSharingFragment() + .requestPasswordForShareViaLink(true, + getCapabilities().getFilesSharingPublicAskForOptionalPassword() + .isTrue()); } } else { diff --git a/src/main/java/com/owncloud/android/ui/activity/ShareActivity.java b/src/main/java/com/owncloud/android/ui/activity/ShareActivity.java index ee8f04b41fb5..8c651db2e93f 100644 --- a/src/main/java/com/owncloud/android/ui/activity/ShareActivity.java +++ b/src/main/java/com/owncloud/android/ui/activity/ShareActivity.java @@ -355,10 +355,11 @@ private void onCreateShareViaLinkOperationFinish(CreateShareViaLinkOperation ope // Try with password before giving up; see also ShareFileFragment#OnShareViaLinkListener ShareFileFragment shareFileFragment = getShareFileFragment(); - if (shareFileFragment != null - && shareFileFragment.isAdded()) { // only if added to the view hierarchy!! + if (shareFileFragment != null && shareFileFragment.isAdded()) { // only if added to the view hierarchy!! - shareFileFragment.requestPasswordForShareViaLink(true); + boolean askForPassword = getCapabilities().getFilesSharingPublicAskForOptionalPassword().isTrue(); + + shareFileFragment.requestPasswordForShareViaLink(true, askForPassword); } } else { diff --git a/src/main/java/com/owncloud/android/ui/dialog/SendShareDialog.java b/src/main/java/com/owncloud/android/ui/dialog/SendShareDialog.java index d7b7c99bc607..a27d4e9b1143 100644 --- a/src/main/java/com/owncloud/android/ui/dialog/SendShareDialog.java +++ b/src/main/java/com/owncloud/android/ui/dialog/SendShareDialog.java @@ -18,6 +18,7 @@ import com.owncloud.android.R; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.lib.common.utils.Log_OC; +import com.owncloud.android.lib.resources.status.OCCapability; import com.owncloud.android.ui.activity.FileActivity; import com.owncloud.android.ui.activity.FileDisplayActivity; import com.owncloud.android.ui.adapter.SendButtonAdapter; @@ -26,6 +27,8 @@ import com.owncloud.android.utils.MimeTypeUtil; import com.owncloud.android.utils.ThemeUtils; +import org.jetbrains.annotations.NotNull; + import java.util.ArrayList; import java.util.List; @@ -60,6 +63,7 @@ public class SendShareDialog extends BottomSheetDialogFragment { private static final String KEY_OCFILE = "KEY_OCFILE"; private static final String KEY_SHARING_PUBLIC_PASSWORD_ENFORCED = "KEY_SHARING_PUBLIC_PASSWORD_ENFORCED"; + private static final String KEY_SHARING_PUBLIC_ASK_FOR_PASSWORD = "KEY_SHARING_PUBLIC_ASK_FOR_PASSWORD"; private static final String KEY_HIDE_NCSHARING_OPTIONS = "KEY_HIDE_NCSHARING_OPTIONS"; private static final String TAG = SendShareDialog.class.getSimpleName(); public static final String PACKAGE_NAME = "PACKAGE_NAME"; @@ -69,16 +73,20 @@ public class SendShareDialog extends BottomSheetDialogFragment { private OCFile file; private boolean hideNcSharingOptions; private boolean sharingPublicPasswordEnforced; + private boolean sharingPublicAskForPassword; private FileOperationsHelper fileOperationsHelper; - public static SendShareDialog newInstance(OCFile file, boolean hideNcSharingOptions, boolean sharingPublicPasswordEnforced) { + public static SendShareDialog newInstance(OCFile file, boolean hideNcSharingOptions, OCCapability capability) { SendShareDialog dialogFragment = new SendShareDialog(); Bundle args = new Bundle(); args.putParcelable(KEY_OCFILE, file); args.putBoolean(KEY_HIDE_NCSHARING_OPTIONS, hideNcSharingOptions); - args.putBoolean(KEY_SHARING_PUBLIC_PASSWORD_ENFORCED, sharingPublicPasswordEnforced); + args.putBoolean(KEY_SHARING_PUBLIC_PASSWORD_ENFORCED, + capability.getFilesSharingPublicPasswordEnforced().isTrue()); + args.putBoolean(KEY_SHARING_PUBLIC_ASK_FOR_PASSWORD, + capability.getFilesSharingPublicAskForOptionalPassword().isTrue()); dialogFragment.setArguments(args); return dialogFragment; @@ -93,11 +101,14 @@ public void onCreate(@Nullable Bundle savedInstanceState) { file = getArguments().getParcelable(KEY_OCFILE); hideNcSharingOptions = getArguments().getBoolean(KEY_HIDE_NCSHARING_OPTIONS, false); sharingPublicPasswordEnforced = getArguments().getBoolean(KEY_SHARING_PUBLIC_PASSWORD_ENFORCED, false); + sharingPublicAskForPassword = getArguments().getBoolean(KEY_SHARING_PUBLIC_ASK_FOR_PASSWORD); } @Nullable @Override - public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + public View onCreateView(@NotNull LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { view = inflater.inflate(R.layout.send_share_fragment, container, false); @@ -178,7 +189,9 @@ private void shareByLink() { } private void requestPasswordForShareViaLink() { - SharePasswordDialogFragment dialog = SharePasswordDialogFragment.newInstance(file, true); + SharePasswordDialogFragment dialog = SharePasswordDialogFragment.newInstance(file, + true, + sharingPublicAskForPassword); dialog.show(getFragmentManager(), SharePasswordDialogFragment.PASSWORD_FRAGMENT); } diff --git a/src/main/java/com/owncloud/android/ui/dialog/SharePasswordDialogFragment.java b/src/main/java/com/owncloud/android/ui/dialog/SharePasswordDialogFragment.java index cb8b76e174e7..389fac994b55 100644 --- a/src/main/java/com/owncloud/android/ui/dialog/SharePasswordDialogFragment.java +++ b/src/main/java/com/owncloud/android/ui/dialog/SharePasswordDialogFragment.java @@ -55,11 +55,13 @@ public class SharePasswordDialogFragment extends DialogFragment implements Dialo private static final String ARG_FILE = "FILE"; private static final String ARG_SHARE = "SHARE"; private static final String ARG_CREATE_SHARE = "CREATE_SHARE"; + private static final String ARG_ASK_FOR_PASSWORD = "ASK_FOR_PASSWORD"; public static final String PASSWORD_FRAGMENT = "PASSWORD_FRAGMENT"; private OCFile file; private OCShare share; private boolean createShare; + private boolean askForPassword; @Override public void onStart() { @@ -81,11 +83,12 @@ public void onStart() { * is bound to it. * @return Dialog ready to show. */ - public static SharePasswordDialogFragment newInstance(OCFile file, boolean createShare) { + public static SharePasswordDialogFragment newInstance(OCFile file, boolean createShare, boolean askForPassword) { SharePasswordDialogFragment frag = new SharePasswordDialogFragment(); Bundle args = new Bundle(); args.putParcelable(ARG_FILE, file); args.putBoolean(ARG_CREATE_SHARE, createShare); + args.putBoolean(ARG_ASK_FOR_PASSWORD, askForPassword); frag.setArguments(args); return frag; } @@ -116,6 +119,7 @@ public Dialog onCreateDialog(Bundle savedInstanceState) { file = getArguments().getParcelable(ARG_FILE); share = getArguments().getParcelable(ARG_SHARE); createShare = getArguments().getBoolean(ARG_CREATE_SHARE, false); + askForPassword = getArguments().getBoolean(ARG_ASK_FOR_PASSWORD, false); // Inflate the layout for the dialog LayoutInflater inflater = getActivity().getLayoutInflater(); @@ -130,6 +134,13 @@ public Dialog onCreateDialog(Bundle savedInstanceState) { inputText.setText(""); inputText.requestFocus(); + int title; + if (askForPassword) { + title = R.string.share_link_optional_password_title; + } else { + title = R.string.share_link_password_title; + } + // Build the dialog AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.Theme_ownCloud_Dialog_NoButtonBarStyle); @@ -137,7 +148,7 @@ public Dialog onCreateDialog(Bundle savedInstanceState) { .setPositiveButton(R.string.common_ok, this) .setNegativeButton(R.string.common_cancel, this) .setNeutralButton(R.string.common_delete, this) - .setTitle(R.string.share_link_password_title); + .setTitle(title); Dialog d = builder.create(); Window window = d.getWindow(); @@ -153,11 +164,9 @@ public void onClick(DialogInterface dialog, int which) { if (which == AlertDialog.BUTTON_POSITIVE) { String password = ((TextView) (getDialog().findViewById(R.id.share_password))).getText().toString(); - if (TextUtils.isEmpty(password)) { - DisplayUtils.showSnackMessage( - getActivity().findViewById(android.R.id.content), - R.string.share_link_empty_password - ); + if (!askForPassword && TextUtils.isEmpty(password)) { + DisplayUtils.showSnackMessage(getActivity().findViewById(android.R.id.content), + R.string.share_link_empty_password); return; } @@ -172,6 +181,12 @@ public void onClick(DialogInterface dialog, int which) { } else { setPassword(share, null); } + } else if (which == AlertDialog.BUTTON_NEGATIVE && askForPassword) { + if (share == null) { + setPassword(createShare, file, null); + } else { + setPassword(share, null); + } } } diff --git a/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java b/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java index e5e25fe30cb4..6b136b8a3727 100644 --- a/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java +++ b/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java @@ -320,10 +320,11 @@ public void toggleShareByLink() { } private void createShareLink() { - if (capabilities != null && - capabilities.getFilesSharingPublicPasswordEnforced().isTrue()) { + if (capabilities != null && (capabilities.getFilesSharingPublicPasswordEnforced().isTrue() || + capabilities.getFilesSharingPublicAskForOptionalPassword().isTrue())) { // password enforced by server, request to the user before trying to create - requestPasswordForShareViaLink(true); + requestPasswordForShareViaLink(true, + capabilities.getFilesSharingPublicAskForOptionalPassword().isTrue()); } else { // create without password if not enforced by server or we don't know if enforced; @@ -417,7 +418,8 @@ private boolean optionsItemSelected(MenuItem item) { return true; case R.id.action_password: { - requestPasswordForShareViaLink(false); + requestPasswordForShareViaLink(false, + capabilities.getFilesSharingPublicAskForOptionalPassword().isTrue()); return true; } case R.id.action_share_expiration_date: { @@ -527,12 +529,14 @@ public void updateNoteToShare(OCShare share, String note) { /** * Starts a dialog that requests a password to the user to protect a share link. * - * @param createShare When 'true', the request for password will be followed by the creation of a new - * public link; when 'false', a public share is assumed to exist, and the password - * is bound to it. + * @param createShare When 'true', the request for password will be followed by the creation of a new public + * link; when 'false', a public share is assumed to exist, and the password is bound to it. + * @param askForPassword if true, password is optional */ - public void requestPasswordForShareViaLink(boolean createShare) { - SharePasswordDialogFragment dialog = SharePasswordDialogFragment.newInstance(file, createShare); + public void requestPasswordForShareViaLink(boolean createShare, boolean askForPassword) { + SharePasswordDialogFragment dialog = SharePasswordDialogFragment.newInstance(file, + createShare, + askForPassword); dialog.show(getChildFragmentManager(), SharePasswordDialogFragment.PASSWORD_FRAGMENT); } diff --git a/src/main/java/com/owncloud/android/ui/fragment/ShareFileFragment.java b/src/main/java/com/owncloud/android/ui/fragment/ShareFileFragment.java index 9ff6c2867f3c..860ab879f356 100644 --- a/src/main/java/com/owncloud/android/ui/fragment/ShareFileFragment.java +++ b/src/main/java/com/owncloud/android/ui/fragment/ShareFileFragment.java @@ -285,15 +285,14 @@ public void onCheckedChanged(CompoundButton switchView, boolean isChecked) { return; } if (isChecked) { - if (mCapabilities != null && - mCapabilities.getFilesSharingPublicPasswordEnforced().isTrue()) { + if (mCapabilities != null && (mCapabilities.getFilesSharingPublicPasswordEnforced().isTrue() || + mCapabilities.getFilesSharingPublicAskForOptionalPassword().isTrue())) { // password enforced by server, request to the user before trying to create - requestPasswordForShareViaLink(true); - + requestPasswordForShareViaLink(true, + mCapabilities.getFilesSharingPublicAskForOptionalPassword().isTrue()); } else { // create without password if not enforced by server or we don't know if enforced; - ((FileActivity) getActivity()).getFileOperationsHelper(). - shareFileViaLink(mFile, null); + ((FileActivity) getActivity()).getFileOperationsHelper().shareFileViaLink(mFile, null); // ShareActivity#onCreateShareViaLinkOperationFinish will take care if password // is enforced by the server but app doesn't know, or if server version is @@ -301,8 +300,7 @@ public void onCheckedChanged(CompoundButton switchView, boolean isChecked) { } } else { - ((FileActivity) getActivity()).getFileOperationsHelper(). - unshareFileViaLink(mFile); + ((FileActivity) getActivity()).getFileOperationsHelper().unshareFileViaLink(mFile); } // undo the toggle to grant the view will be correct if any intermediate dialog is cancelled or @@ -429,10 +427,10 @@ public void onCheckedChanged(CompoundButton switchView, boolean isChecked) { return; } if (isChecked) { - requestPasswordForShareViaLink(false); + requestPasswordForShareViaLink(false, + mCapabilities.getFilesSharingPublicAskForOptionalPassword().isTrue()); } else { - ((FileActivity) getActivity()).getFileOperationsHelper(). - setPasswordToShareViaLink(mFile, ""); // "" clears + ((FileActivity) getActivity()).getFileOperationsHelper().setPasswordToShareViaLink(mFile, ""); // clears } // undo the toggle to grant the view will be correct if the dialog is cancelled @@ -450,7 +448,8 @@ public void onCheckedChanged(CompoundButton switchView, boolean isChecked) { @Override public void onClick(View passwordView) { if (mPublicShare != null && mPublicShare.isPasswordProtected()) { - requestPasswordForShareViaLink(false); + requestPasswordForShareViaLink(false, + mCapabilities.getFilesSharingPublicAskForOptionalPassword().isTrue()); } } } @@ -890,12 +889,14 @@ private void hidePublicShare() { /** * Starts a dialog that requests a password to the user to protect a share link. * - * @param createShare When 'true', the request for password will be followed by the creation of a new - * public link; when 'false', a public share is assumed to exist, and the password - * is bound to it. + * @param createShare When 'true', the request for password will be followed by the creation of a new public + * link; when 'false', a public share is assumed to exist, and the password is bound to it. + * @param askForPassword if true, password is optional */ - public void requestPasswordForShareViaLink(boolean createShare) { - SharePasswordDialogFragment dialog = SharePasswordDialogFragment.newInstance(mFile, createShare); + public void requestPasswordForShareViaLink(boolean createShare, boolean askForPassword) { + SharePasswordDialogFragment dialog = SharePasswordDialogFragment.newInstance(mFile, + createShare, + askForPassword); dialog.show(getFragmentManager(), SharePasswordDialogFragment.PASSWORD_FRAGMENT); } diff --git a/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java b/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java index 38b0a7810920..c5e9eb3db6c8 100755 --- a/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java +++ b/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java @@ -717,10 +717,7 @@ public void sendShareFile(OCFile file, boolean hideNcSharingOptions) { ft.addToBackStack(null); OCCapability capability = mFileActivity.getStorageManager().getCapability(mFileActivity.getAccount().name); - SendShareDialog mSendShareDialog; - - mSendShareDialog = SendShareDialog.newInstance(file, hideNcSharingOptions, - capability.getFilesSharingPublicPasswordEnforced().isTrue()); + SendShareDialog mSendShareDialog = SendShareDialog.newInstance(file, hideNcSharingOptions, capability); mSendShareDialog.setFileOperationsHelper(this); mSendShareDialog.show(ft, "TAG_SEND_SHARE_DIALOG"); } diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 45a350a5e21a..45859a5c5df3 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -350,6 +350,7 @@ Unable to update. Please check whether the file exists An error occurred while trying to update the share Enter a password + Enter an optional password You must enter a password Send