Explorar o código

Update share permissions when 'DONE' button is clicked

David A. Velasco %!s(int64=9) %!d(string=hai) anos
pai
achega
6f5d09ada2

+ 95 - 40
src/com/owncloud/android/datamodel/FileDataStorageManager.java

@@ -100,7 +100,7 @@ public class FileDataStorageManager {
 
 
     public OCFile getFileByPath(String path) {
-        Cursor c = getCursorForValue(ProviderTableMeta.FILE_PATH, path);
+        Cursor c = getFileCursorForValue(ProviderTableMeta.FILE_PATH, path);
         OCFile file = null;
         if (c.moveToFirst()) {
             file = createFileInstance(c);
@@ -114,7 +114,7 @@ public class FileDataStorageManager {
 
 
     public OCFile getFileById(long id) {
-        Cursor c = getCursorForValue(ProviderTableMeta._ID, String.valueOf(id));
+        Cursor c = getFileCursorForValue(ProviderTableMeta._ID, String.valueOf(id));
         OCFile file = null;
         if (c.moveToFirst()) {
             file = createFileInstance(c);
@@ -124,7 +124,7 @@ public class FileDataStorageManager {
     }
 
     public OCFile getFileByLocalPath(String path) {
-        Cursor c = getCursorForValue(ProviderTableMeta.FILE_STORAGE_PATH, path);
+        Cursor c = getFileCursorForValue(ProviderTableMeta.FILE_STORAGE_PATH, path);
         OCFile file = null;
         if (c.moveToFirst()) {
             file = createFileInstance(c);
@@ -831,7 +831,7 @@ public class FileDataStorageManager {
         return retval;
     }
 
-    private Cursor getCursorForValue(String key, String value) {
+    private Cursor getFileCursorForValue(String key, String value) {
         Cursor c = null;
         if (getContentResolver() != null) {
             c = getContentResolver()
@@ -936,7 +936,7 @@ public class FileDataStorageManager {
         cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getRemoteId());
         cv.put(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER, mAccount.name);
 
-        if (shareExists(share.getRemoteId())) {// for renamed files; no more delete and create
+        if (shareExistsForRemoteId(share.getRemoteId())) {// for renamed files; no more delete and create
             overriden = true;
             if (getContentResolver() != null) {
                 getContentResolver().update(ProviderTableMeta.CONTENT_URI_SHARE, cv,
@@ -978,6 +978,95 @@ public class FileDataStorageManager {
         return overriden;
     }
 
+    /**
+     * Retrieves an stored {@link OCShare} given its id.
+     *
+     * @param id    Identifier.
+     * @return      Stored {@link OCShare} given its id.
+     */
+    public OCShare getShareById(long id) {
+        OCShare share = null;
+        Cursor c = getShareCursorForValue(
+                ProviderTableMeta._ID,
+                String.valueOf(id)
+        );
+        if (c != null) {
+            if (c.moveToFirst()) {
+                share = createShareInstance(c);
+            }
+            c.close();
+        }
+        return share;
+    }
+
+
+    /**
+     * Checks the existance of an stored {@link OCShare} matching the given remote id (not to be confused with
+     * the local id) in the current account.
+     *
+     * @param remoteId      Remote of the share in the server.
+     * @return              'True' if a matching {@link OCShare} is stored in the current account.
+     */
+    private boolean shareExistsForRemoteId(long remoteId) {
+        return shareExistsForValue(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, String.valueOf(remoteId));
+    }
+
+
+    /**
+     * Checks the existance of an stored {@link OCShare} in the current account
+     * matching a given column and a value for that column
+     *
+     * @param key           Name of the column to match.
+     * @param value         Value of the column to match.
+     * @return              'True' if a matching {@link OCShare} is stored in the current account.
+     */
+    private boolean shareExistsForValue(String key, String value) {
+        Cursor c = getShareCursorForValue(key, value);
+        boolean retval = c.moveToFirst();
+        c.close();
+        return retval;
+    }
+
+
+    /**
+     * Gets a {@link Cursor} for an stored {@link OCShare} in the current account
+     * matching a given column and a value for that column
+     *
+     * @param key           Name of the column to match.
+     * @param value         Value of the column to match.
+     * @return              'True' if a matching {@link OCShare} is stored in the current account.
+     */
+    private Cursor getShareCursorForValue(String key, String value) {
+        Cursor c;
+        if (getContentResolver() != null) {
+            c = getContentResolver()
+                    .query(ProviderTableMeta.CONTENT_URI_SHARE,
+                            null,
+                            key + "=? AND "
+                                + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?",
+                            new String[]{value, mAccount.name},
+                            null
+                    );
+        } else {
+            try {
+                c = getContentProviderClient().query(
+                        ProviderTableMeta.CONTENT_URI_SHARE,
+                        null,
+                        key + "=? AND "
+                                + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?",
+                        new String[]{value, mAccount.name},
+                        null
+                );
+            } catch (RemoteException e) {
+                Log_OC.w(TAG,
+                        "Could not get details, assuming share does not exist: "+ e.getMessage());
+                c = null;
+            }
+        }
+        return c;
+    }
+
+
 
     /**
      * Get first share bound to a file with a known path and given {@link ShareType}.
@@ -1074,40 +1163,6 @@ public class FileDataStorageManager {
         return share;
     }
 
-    private boolean shareExists(String cmp_key, String value) {
-        Cursor c;
-        if (getContentResolver() != null) {
-            c = getContentResolver()
-                    .query(ProviderTableMeta.CONTENT_URI_SHARE,
-                            null,
-                            cmp_key + "=? AND "
-                                    + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER
-                                    + "=?",
-                            new String[]{value, mAccount.name}, null);
-        } else {
-            try {
-                c = getContentProviderClient().query(
-                        ProviderTableMeta.CONTENT_URI_SHARE,
-                        null,
-                        cmp_key + "=? AND "
-                                + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?",
-                        new String[]{value, mAccount.name}, null);
-            } catch (RemoteException e) {
-                Log_OC.e(TAG,
-                        "Couldn't determine file existance, assuming non existance: "
-                                + e.getMessage());
-                return false;
-            }
-        }
-        boolean retval = c.moveToFirst();
-        c.close();
-        return retval;
-    }
-
-    private boolean shareExists(long remoteId) {
-        return shareExists(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, String.valueOf(remoteId));
-    }
-
     private void resetShareFlagsInAllFiles() {
         ContentValues cv = new ContentValues();
         cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, false);
@@ -1217,7 +1272,7 @@ public class FileDataStorageManager {
                 cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getRemoteId());
                 cv.put(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER, mAccount.name);
 
-                if (shareExists(share.getRemoteId())) {
+                if (shareExistsForRemoteId(share.getRemoteId())) {
                     // updating an existing file
                     operations.add(
                             ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI_SHARE).

+ 21 - 0
src/com/owncloud/android/files/FileOperationsHelper.java

@@ -39,6 +39,7 @@ import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
 import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
 import com.owncloud.android.lib.common.network.WebdavUtils;
 import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.lib.resources.shares.OCShare;
 import com.owncloud.android.lib.resources.shares.ShareType;
 import com.owncloud.android.lib.resources.status.OwnCloudVersion;
 import com.owncloud.android.services.OperationsService;
@@ -387,6 +388,26 @@ public class FileOperationsHelper {
     }
 
 
+    /**
+     * Updates a share on a file to set its access permissions.
+     * Starts a request to do it in {@link OperationsService}
+     *
+     * @param share                     {@link OCShare} instance which permissions will be updated.
+     * @param permissions               New permissions to set. A value <= 0 makes no update.
+     */
+    public void setPermissionsToShare(OCShare share, int permissions) {
+        Intent updateShareIntent = new Intent(mFileActivity, OperationsService.class);
+        updateShareIntent.setAction(OperationsService.ACTION_UPDATE_SHARE);
+        updateShareIntent.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount());
+        updateShareIntent.putExtra(OperationsService.EXTRA_SHARE_ID, share.getId());
+        updateShareIntent.putExtra(
+                OperationsService.EXTRA_SHARE_PERMISSIONS,
+                permissions
+        );
+        queueShareIntent(updateShareIntent);
+    }
+
+
     /**
      * @return 'True' if the server supports the Search Users API
      */

+ 115 - 0
src/com/owncloud/android/operations/UpdateSharePermissionsOperation.java

@@ -0,0 +1,115 @@
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2,
+ *   as published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+package com.owncloud.android.operations;
+
+import com.owncloud.android.lib.common.OwnCloudClient;
+import com.owncloud.android.lib.common.operations.RemoteOperation;
+import com.owncloud.android.lib.common.operations.RemoteOperationResult;
+import com.owncloud.android.lib.resources.files.FileUtils;
+import com.owncloud.android.lib.resources.shares.GetRemoteShareOperation;
+import com.owncloud.android.lib.resources.shares.OCShare;
+import com.owncloud.android.lib.resources.shares.UpdateRemoteShareOperation;
+import com.owncloud.android.operations.common.SyncOperation;
+
+
+/**
+ * Updates an existing private share for a given file
+ */
+
+public class UpdateSharePermissionsOperation extends SyncOperation {
+
+    private long mShareId;
+    private int mPermissions;
+    private String mPath;
+
+    /**
+     * Constructor
+     *
+     * @param shareId       Private {@link OCShare} to update. Mandatory argument
+     */
+    public UpdateSharePermissionsOperation(long shareId) {
+        mShareId = shareId;
+        mPermissions = -1;
+    }
+
+
+    /**
+     * Set permissions to update in private share.
+     *
+     * @param permissions   Permissions to set to the private share.
+     *                      Values <= 0 result in no update applied to the permissions.
+     */
+    public void setPermissions(int permissions) {
+        mPermissions = permissions;
+    }
+
+
+    @Override
+    protected RemoteOperationResult run(OwnCloudClient client) {
+
+        OCShare share = getStorageManager().getShareById(mShareId); // ShareType.USER | ShareType.GROUP
+
+        if (share == null) {
+            // TODO try to get remote share before failing?
+            return new RemoteOperationResult(
+                    RemoteOperationResult.ResultCode.SHARE_NOT_FOUND
+            );
+        }
+
+        mPath = share.getPath();
+
+        // Update remote share with password
+        UpdateRemoteShareOperation updateOp = new UpdateRemoteShareOperation(
+            share.getRemoteId()
+        );
+        updateOp.setPermissions(mPermissions);
+        RemoteOperationResult result = updateOp.execute(client);
+
+        if (result.isSuccess()) {
+            RemoteOperation getShareOp = new GetRemoteShareOperation(share.getRemoteId());
+            result = getShareOp.execute(client);
+            if (result.isSuccess()) {
+                share = (OCShare) result.getData().get(0);
+                // TODO check permissions are being saved
+                updateData(share);
+            }
+        }
+
+        return result;
+    }
+
+    public String getPath() {
+        return mPath;
+    }
+
+    private void updateData(OCShare share) {
+        // Update DB with the response
+        share.setPath(mPath);   // TODO - check if may be moved to UpdateRemoteShareOperation
+        if (mPath.endsWith(FileUtils.PATH_SEPARATOR)) {
+            share.setIsFolder(true);
+        } else {
+            share.setIsFolder(false);
+        }
+        getStorageManager().saveShare(share);
+    }
+
+}
+

+ 5 - 5
src/com/owncloud/android/operations/UpdateShareViaLinkOperation.java

@@ -99,15 +99,15 @@ public class UpdateShareViaLinkOperation extends SyncOperation {
         }
 
         // Update remote share with password
-        UpdateRemoteShareOperation udpateOp = new UpdateRemoteShareOperation(
+        UpdateRemoteShareOperation updateOp = new UpdateRemoteShareOperation(
             publicShare.getRemoteId()
         );
-        udpateOp.setPassword(mPassword);
-        udpateOp.setExpirationDate(mExpirationDateInMillis);
-        RemoteOperationResult result = udpateOp.execute(client);
+        updateOp.setPassword(mPassword);
+        updateOp.setExpirationDate(mExpirationDateInMillis);
+        RemoteOperationResult result = updateOp.execute(client);
 
         if (result.isSuccess()) {
-            // Retrieve updated share / save directly with password? -> no; the password is not be saved
+            // Retrieve updated share / save directly with password? -> no; the password is not to be saved
             RemoteOperation getShareOp = new GetRemoteShareOperation(publicShare.getRemoteId());
             result = getShareOp.execute(client);
             if (result.isSuccess()) {

+ 10 - 3
src/com/owncloud/android/services/OperationsService.java

@@ -64,6 +64,7 @@ import com.owncloud.android.operations.RenameFileOperation;
 import com.owncloud.android.operations.SynchronizeFileOperation;
 import com.owncloud.android.operations.SynchronizeFolderOperation;
 import com.owncloud.android.operations.UnshareOperation;
+import com.owncloud.android.operations.UpdateSharePermissionsOperation;
 import com.owncloud.android.operations.UpdateShareViaLinkOperation;
 import com.owncloud.android.operations.common.SyncOperation;
 
@@ -94,8 +95,8 @@ public class OperationsService extends Service {
     public static final String EXTRA_SHARE_TYPE = "SHARE_TYPE";
     public static final String EXTRA_SHARE_WITH = "SHARE_WITH";
     public static final String EXTRA_SHARE_EXPIRATION_DATE_IN_MILLIS = "SHARE_EXPIRATION_YEAR";
-    public static final String EXTRA_SHARE_EXPIRATION_MONTH_OF_YEAR = "SHARE_EXPIRATION_MONTH_OF_YEAR";
-    public static final String EXTRA_SHARE_EXPIRATION_DAY_OF_MONTH = "SHARE_EXPIRATION_DAY_OF_MONTH";
+    public static final String EXTRA_SHARE_PERMISSIONS = "SHARE_PERMISSIONS";
+    public static final String EXTRA_SHARE_ID = "SHARE_ID";
 
     public static final String EXTRA_COOKIE = "COOKIE";
 
@@ -571,7 +572,8 @@ public class OperationsService extends Service {
 
                 } else if (ACTION_UPDATE_SHARE.equals(action)) {
                     String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
-                    if (remotePath.length() > 0) {
+                    long shareId = operationIntent.getLongExtra(EXTRA_SHARE_ID, -1);
+                    if (remotePath != null && remotePath.length() > 0) {
                         operation = new UpdateShareViaLinkOperation(remotePath);
 
                         String password = operationIntent.getStringExtra(EXTRA_SHARE_PASSWORD);
@@ -584,6 +586,11 @@ public class OperationsService extends Service {
                         ((UpdateShareViaLinkOperation)operation).setExpirationDate(
                                 expirationDate
                         );
+
+                    } else if (shareId > 0) {
+                        operation = new UpdateSharePermissionsOperation(shareId);
+                        int permissions = operationIntent.getIntExtra(EXTRA_SHARE_PERMISSIONS, 1);
+                        ((UpdateSharePermissionsOperation)operation).setPermissions(permissions);
                     }
 
                 } else if (action.equals(ACTION_CREATE_SHARE_WITH_SHAREE)) {

+ 74 - 10
src/com/owncloud/android/ui/fragment/EditShareFragment.java

@@ -27,18 +27,15 @@ import android.support.v4.app.Fragment;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.Button;
 import android.widget.CheckBox;
 import android.widget.CompoundButton;
 import android.widget.TextView;
-import android.widget.Toast;
 
 import com.owncloud.android.R;
-import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.resources.shares.OCShare;
-import com.owncloud.android.lib.resources.shares.ShareType;
+import com.owncloud.android.lib.resources.shares.SharePermissionsBuilder;
 import com.owncloud.android.ui.activity.FileActivity;
 
 public class EditShareFragment extends Fragment {
@@ -110,6 +107,15 @@ public class EditShareFragment extends Fragment {
     }
 
 
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+        Log_OC.d(TAG, "onActivityCreated");
+        getActivity().setTitle(mShare.getSharedWithDisplayName());
+    }
+
+
     /**
      * {@inheritDoc}
      */
@@ -350,17 +356,75 @@ public class EditShareFragment extends Fragment {
         doneButton.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                Toast.makeText(getActivity(), "TODO - update permissions in server", Toast.LENGTH_LONG).show();
+                SharePermissionsBuilder spb = new SharePermissionsBuilder();
+                spb.setSharePermission(getCanShareCheckBox().isChecked());
+                if (mFile.isFolder()) {
+                    spb.setUpdatePermission(getCanEditChangeCheckBox().isChecked())
+                        .setCreatePermission(getCanEditCreateCheckBox().isChecked())
+                        .setDeletePermission(getCanEditDeleteCheckBox().isChecked());
+                } else {
+                    spb.setUpdatePermission(getCanEditCheckBox().isChecked());
+                }
+                int permissions = spb.build();
+
+                ((FileActivity) getActivity()).getFileOperationsHelper().
+                        setPermissionsToShare(
+                                mShare,
+                                permissions
+                        );
             }
         });
     }
 
+    /**
+     * Shortcut to access {@link CheckBox} R.id.canShareCheckBox
+     *
+     * @return  {@link CheckBox} R.id.canShareCheckBox or null if called before
+     *          {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)} finished.
+     */
+    private CheckBox getCanShareCheckBox() {
+        return (CheckBox) getView().findViewById(R.id.canShareCheckBox);
+    }
 
-    @Override
-    public void onActivityCreated(Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
-        Log_OC.d(TAG, "onActivityCreated");
-        getActivity().setTitle(mShare.getSharedWithDisplayName());
+    /**
+     * Shortcut to access {@link CheckBox} R.id.canEditCheckBox
+     *
+     * @return  {@link CheckBox} R.id.canEditCheckBox or null if called before
+     *          {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)} finished.
+     */
+    private CheckBox getCanEditCheckBox() {
+        return (CheckBox) getView().findViewById(R.id.canEditCheckBox);
+    }
+
+    /**
+     * Shortcut to access {@link CheckBox} R.id.canEditCreateCheckBox
+     *
+     * @return  {@link CheckBox} R.id.canEditCreateCheckBox or null if called before
+     *          {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)} finished.
+     */
+    private CheckBox getCanEditCreateCheckBox() {
+        return (CheckBox) getView().findViewById(R.id.canEditCreateCheckBox);
+    }
+
+    /**
+     * Shortcut to access {@link CheckBox} R.id.canEditChangeCheckBox
+     *
+     * @return  {@link CheckBox} R.id.canEditChangeCheckBox or null if called before
+     *          {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)} finished.
+     */
+    private CheckBox getCanEditChangeCheckBox() {
+        return (CheckBox) getView().findViewById(R.id.canEditChangeCheckBox);
+    }
+
+    /**
+     * Shortcut to access {@link CheckBox} R.id.canEditDeleteCheckBox
+     *
+     * @return  {@link CheckBox} R.id.canEditDeleteCheckBox or null if called before
+     *          {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)} finished.
+     */
+    private CheckBox getCanEditDeleteCheckBox() {
+        return (CheckBox) getView().findViewById(R.id.canEditDeleteCheckBox);
     }
 
+
 }