Эх сурвалжийг харах

Merge pull request #1191 from nextcloud/bugfix/noid/handle-401

Start the reauth webview also when there is no getParentController()
Marcel Hibbe 4 жил өмнө
parent
commit
b930f1365b

+ 67 - 15
app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java

@@ -23,6 +23,7 @@
 package com.nextcloud.talk.controllers;
 
 import android.animation.AnimatorInflater;
+import android.annotation.SuppressLint;
 import android.app.SearchManager;
 import android.content.Context;
 import android.content.Intent;
@@ -32,6 +33,7 @@ import android.os.Bundle;
 import android.os.Handler;
 import android.text.InputType;
 import android.text.TextUtils;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
@@ -85,6 +87,7 @@ import com.nextcloud.talk.events.BottomSheetLockEvent;
 import com.nextcloud.talk.events.EventStatus;
 import com.nextcloud.talk.events.MoreMenuClickEvent;
 import com.nextcloud.talk.interfaces.ConversationMenuInterface;
+import com.nextcloud.talk.jobs.AccountRemovalWorker;
 import com.nextcloud.talk.jobs.ContactAddressBookWorker;
 import com.nextcloud.talk.jobs.DeleteConversationWorker;
 import com.nextcloud.talk.models.database.UserEntity;
@@ -232,7 +235,7 @@ public class ConversationsListController extends BaseController implements Searc
             }
 
             ImageRequest imageRequest = DisplayUtils.getImageRequestForUrl(ApiUtils.getUrlForAvatarWithNameAndPixels(currentUser.getBaseUrl(),
-                    currentUser.getUserId(), avatarSize), currentUser);
+                                                                                                                     currentUser.getUserId(), avatarSize), currentUser);
 
             ImagePipeline imagePipeline = Fresco.getImagePipeline();
             DataSource<CloseableReference<CloseableImage>> dataSource = imagePipeline.fetchDecodedImage(imageRequest, null);
@@ -260,7 +263,9 @@ public class ConversationsListController extends BaseController implements Searc
     @Override
     protected void onAttach(@NonNull View view) {
         super.onAttach(view);
-        eventBus.register(this);
+        if (!eventBus.isRegistered(this)) {
+            eventBus.register(this);
+        }
 
         currentUser = userUtils.getCurrentUser();
 
@@ -331,7 +336,7 @@ public class ConversationsListController extends BaseController implements Searc
                     DisplayUtils.applyColorToStatusBar(
                             activity,
                             ResourcesCompat.getColor(getResources(), R.color.appbar, null)
-                    );
+                                                      );
                 }
             });
         }
@@ -343,7 +348,7 @@ public class ConversationsListController extends BaseController implements Searc
                     DisplayUtils.applyColorToStatusBar(
                             activity,
                             ResourcesCompat.getColor(getResources(), R.color.bg_default, null)
-                    );
+                                                      );
                 }
             } else {
                 searchView.post(() -> searchView.setQuery("", true));
@@ -365,19 +370,19 @@ public class ConversationsListController extends BaseController implements Searc
                     activity.appBar.setStateListAnimator(AnimatorInflater.loadStateListAnimator(
                             activity.appBar.getContext(),
                             R.animator.appbar_elevation_off)
-                    );
+                                                        );
                     activity.toolbar.setVisibility(View.GONE);
                     activity.searchCardView.setVisibility(View.VISIBLE);
                     if (getResources() != null) {
                         DisplayUtils.applyColorToStatusBar(
                                 activity,
                                 ResourcesCompat.getColor(getResources(), R.color.bg_default, null)
-                        );
+                                                          );
                     }
                 }
                 SmoothScrollLinearLayoutManager layoutManager =
                         (SmoothScrollLinearLayoutManager) recyclerView.getLayoutManager();
-                if (layoutManager!=null) {
+                if (layoutManager != null) {
                     layoutManager.scrollToPositionWithOffset(0, 0);
                 }
                 return true;
@@ -400,6 +405,7 @@ public class ConversationsListController extends BaseController implements Searc
         searchItem.expandActionView();
     }
 
+    @SuppressLint("LongLogTag")
     private void fetchData(boolean fromBottomSheet) {
         dispose(null);
 
@@ -462,7 +468,7 @@ public class ConversationsListController extends BaseController implements Searc
                     } else {
                         Collections.sort(callItems, (callItem, t1) ->
                                 Long.compare(((CallItem) t1).getModel().getLastPing(),
-                                        ((CallItem) callItem).getModel().getLastPing()));
+                                             ((CallItem) callItem).getModel().getLastPing()));
                     }
 
                     adapter.updateDataSet(callItems, false);
@@ -476,13 +482,15 @@ public class ConversationsListController extends BaseController implements Searc
                         HttpException exception = (HttpException) throwable;
                         switch (exception.code()) {
                             case 401:
-                                if (getParentController() != null &&
-                                        getParentController().getRouter() != null) {
+                                if (getParentController() != null && getParentController().getRouter() != null) {
+                                    Log.d(TAG, "Starting reauth webview via getParentController()");
                                     getParentController().getRouter().pushController((RouterTransaction.with
-                                            (new WebViewLoginController(currentUser.getBaseUrl(),
-                                                    true))
+                                            (new WebViewLoginController(currentUser.getBaseUrl(), true))
                                             .pushChangeHandler(new VerticalChangeHandler())
                                             .popChangeHandler(new VerticalChangeHandler())));
+                                } else {
+                                    Log.d(TAG, "Starting reauth webview via ConversationsListController");
+                                    showUnauthorizedDialog();
                                 }
                                 break;
                             default:
@@ -726,7 +734,7 @@ public class ConversationsListController extends BaseController implements Searc
                 if (currentUser.hasSpreedFeatureCapability("chat-v2")) {
                     bundle.putParcelable(BundleKeys.INSTANCE.getKEY_ACTIVE_CONVERSATION(), Parcels.wrap(conversation));
                     ConductorRemapping.INSTANCE.remapChatController(getRouter(), currentUser.getId(),
-                            conversation.getToken(), bundle, false);
+                                                                    conversation.getToken(), bundle, false);
                 } else {
                     overridePushHandler(new NoOpControllerChangeHandler());
                     overridePopHandler(new NoOpControllerChangeHandler());
@@ -783,7 +791,7 @@ public class ConversationsListController extends BaseController implements Searc
                 new LovelyStandardDialog(getActivity(), LovelyStandardDialog.ButtonLayout.HORIZONTAL)
                         .setTopColorRes(R.color.nc_darkRed)
                         .setIcon(DisplayUtils.getTintedDrawable(context.getResources(),
-                                R.drawable.ic_delete_black_24dp, R.color.bg_default))
+                                                                R.drawable.ic_delete_black_24dp, R.color.bg_default))
                         .setPositiveButtonColor(context.getResources().getColor(R.color.nc_darkRed))
                         .setTitle(R.string.nc_delete_call)
                         .setMessage(conversation.getDeleteWarningMessage())
@@ -792,7 +800,7 @@ public class ConversationsListController extends BaseController implements Searc
                             public void onClick(View v) {
                                 Data.Builder data = new Data.Builder();
                                 data.putLong(BundleKeys.INSTANCE.getKEY_INTERNAL_USER_ID(),
-                                        conversationMenuBundle.getLong(BundleKeys.INSTANCE.getKEY_INTERNAL_USER_ID()));
+                                             conversationMenuBundle.getLong(BundleKeys.INSTANCE.getKEY_INTERNAL_USER_ID()));
                                 data.putString(BundleKeys.INSTANCE.getKEY_ROOM_TOKEN(), conversation.getToken());
                                 conversationMenuBundle = null;
                                 deleteConversation(data.build());
@@ -811,6 +819,50 @@ public class ConversationsListController extends BaseController implements Searc
         }
     }
 
+    private void showUnauthorizedDialog() {
+        if (getActivity() != null) {
+
+            new LovelyStandardDialog(getActivity(), LovelyStandardDialog.ButtonLayout.HORIZONTAL)
+                    .setTopColorRes(R.color.nc_darkRed)
+                    .setIcon(DisplayUtils.getTintedDrawable(context.getResources(),
+                                                            R.drawable.ic_delete_black_24dp, R.color.bg_default))
+                    .setPositiveButtonColor(context.getResources().getColor(R.color.nc_darkRed))
+                    .setCancelable(false)
+                    .setTitle(R.string.nc_dialog_invalid_password)
+                    .setMessage(R.string.nc_dialog_reauth_or_delete)
+                    .setPositiveButton(R.string.nc_delete, new View.OnClickListener() {
+                        @Override
+                        public void onClick(View v) {
+                            boolean otherUserExists = userUtils.scheduleUserForDeletionWithId(currentUser.getId());
+
+                            OneTimeWorkRequest accountRemovalWork = new OneTimeWorkRequest.Builder(AccountRemovalWorker.class).build();
+                            WorkManager.getInstance().enqueue(accountRemovalWork);
+
+                            if (otherUserExists && getView() != null) {
+                                onViewBound(getView());
+                                onAttach(getView());
+                            } else if (!otherUserExists) {
+                                getRouter().setRoot(RouterTransaction.with(
+                                        new ServerSelectionController())
+                                                            .pushChangeHandler(new VerticalChangeHandler())
+                                                            .popChangeHandler(new VerticalChangeHandler()));
+                            }
+                        }
+                    })
+                    .setNegativeButton(R.string.nc_settings_reauthorize, new View.OnClickListener() {
+                        @Override
+                        public void onClick(View v) {
+                            getRouter().pushController(RouterTransaction.with(
+                                    new WebViewLoginController(currentUser.getBaseUrl(), true))
+                                                               .pushChangeHandler(new VerticalChangeHandler())
+                                                               .popChangeHandler(new VerticalChangeHandler()));
+                        }
+                    })
+                    .setInstanceStateHandler(ID_DELETE_CONVERSATION_DIALOG, saveStateHandler)
+                    .show();
+        }
+    }
+
     private void deleteConversation(Data data) {
         OneTimeWorkRequest deleteConversationWorker =
                 new OneTimeWorkRequest.Builder(DeleteConversationWorker.class).setInputData(data).build();

+ 10 - 3
app/src/main/java/com/nextcloud/talk/controllers/WebViewLoginController.java

@@ -35,6 +35,7 @@ import android.view.View;
 import android.view.ViewGroup;
 import android.webkit.*;
 import android.widget.ProgressBar;
+
 import androidx.annotation.NonNull;
 import androidx.appcompat.app.AppCompatActivity;
 import androidx.core.content.res.ResourcesCompat;
@@ -42,6 +43,7 @@ import androidx.work.OneTimeWorkRequest;
 import androidx.work.WorkManager;
 import autodagger.AutoInjector;
 import butterknife.BindView;
+
 import com.bluelinelabs.conductor.RouterTransaction;
 import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler;
 import com.nextcloud.talk.R;
@@ -64,9 +66,11 @@ import io.reactivex.disposables.Disposable;
 import io.reactivex.schedulers.Schedulers;
 import io.requery.Persistable;
 import io.requery.reactivex.ReactiveEntityStore;
+
 import org.greenrobot.eventbus.EventBus;
 
 import javax.inject.Inject;
+
 import java.lang.reflect.Field;
 import java.net.CookieManager;
 import java.net.URLDecoder;
@@ -233,9 +237,9 @@ public class WebViewLoginController extends BaseController {
                             webView.loadUrl("javascript:var justStore = document.getElementById('user').value = '" + username + "';");
                         } else {
                             webView.loadUrl("javascript: {" +
-                                    "document.getElementById('user').value = '" + username + "';" +
-                                    "document.getElementById('password').value = '" + password + "';" +
-                                    "document.getElementById('submit').click(); };");
+                                                    "document.getElementById('user').value = '" + username + "';" +
+                                                    "document.getElementById('password').value = '" + password + "';" +
+                                                    "document.getElementById('submit').click(); };");
                         }
                     }
                 }
@@ -406,6 +410,9 @@ public class WebViewLoginController extends BaseController {
                     }
                 } else {
                     if (finalMessageType != null) {
+                        // FIXME when the user registers a new account that was setup before (aka
+                        //  ApplicationWideMessageHolder.MessageType.ACCOUNT_UPDATED_NOT_ADDED)
+                        //  The token is not updated in the database and therefor the account not visible/usable
                         ApplicationWideMessageHolder.getInstance().setMessageType(finalMessageType);
                     }
                     getRouter().popToRoot();

+ 86 - 109
app/src/main/java/com/nextcloud/talk/jobs/AccountRemovalWorker.java

@@ -96,7 +96,6 @@ public class AccountRemovalWorker extends Worker {
                     ncApi = retrofit.newBuilder().client(okHttpClient.newBuilder().cookieJar(new
                             JavaNetCookieJar(new CookieManager())).build()).build().create(NcApi.class);
 
-                    String finalCredentials = credentials;
                     ncApi.unregisterDeviceForNotificationsWithNextcloud(credentials, ApiUtils.getUrlNextcloudPush(userEntity
                             .getBaseUrl()))
                             .blockingSubscribe(new Observer<GenericOverall>() {
@@ -114,90 +113,13 @@ public class AccountRemovalWorker extends Worker {
                                         queryMap.put("userPublicKey", finalPushConfigurationState.getUserPublicKey());
                                         queryMap.put("deviceIdentifierSignature",
                                                 finalPushConfigurationState.getDeviceIdentifierSignature());
-
-                                        ncApi.unregisterDeviceForNotificationsWithProxy
-                                                (ApiUtils.getUrlPushProxy(), queryMap)
-                                                .subscribe(new Observer<Void>() {
-                                                    @Override
-                                                    public void onSubscribe(Disposable d) {
-
-                                                    }
-
-                                                    @Override
-                                                    public void onNext(Void aVoid) {
-
-                                                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
-                                                            String groupName = String.format(getApplicationContext().getResources()
-                                                                    .getString(R.string
-                                                                            .nc_notification_channel), userEntity.getUserId(), userEntity.getBaseUrl());
-                                                            CRC32 crc32 = new CRC32();
-                                                            crc32.update(groupName.getBytes());
-                                                            NotificationManager notificationManager =
-                                                                    (NotificationManager) getApplicationContext().getSystemService
-                                                                            (Context.NOTIFICATION_SERVICE);
-
-                                                            if (notificationManager != null) {
-                                                                notificationManager.deleteNotificationChannelGroup(Long
-                                                                        .toString(crc32.getValue()));
-                                                            }
-                                                        }
-
-                                                        WebSocketConnectionHelper.deleteExternalSignalingInstanceForUserEntity(userEntity.getId());
-
-                                                        arbitraryStorageUtils.deleteAllEntriesForAccountIdentifier(userEntity.getId()).subscribe(new Observer() {
-                                                            @Override
-                                                            public void onSubscribe(Disposable d) {
-
-                                                            }
-
-                                                            @Override
-                                                            public void onNext(Object o) {
-                                                                userUtils.deleteUser(userEntity.getId()).subscribe(new CompletableObserver() {
-                                                                    @Override
-                                                                    public void onSubscribe(Disposable d) {
-
-                                                                    }
-
-                                                                    @Override
-                                                                    public void onComplete() {
-
-                                                                    }
-
-                                                                    @Override
-                                                                    public void onError(Throwable e) {
-
-                                                                    }
-                                                                });
-                                                            }
-
-                                                            @Override
-                                                            public void onError(Throwable e) {
-
-                                                            }
-
-                                                            @Override
-                                                            public void onComplete() {
-
-                                                            }
-                                                        });
-                                                    }
-
-                                                    @Override
-                                                    public void onError(Throwable e) {
-
-                                                    }
-
-                                                    @Override
-                                                    public void onComplete() {
-
-                                                    }
-                                                });
+                                        unregisterDeviceForNotificationWithProxy(queryMap, userEntity);
                                     }
                                 }
 
                                 @Override
                                 public void onError(Throwable e) {
-
+                                    Log.e(TAG, "error while trying to unregister Device For Notifications", e);
                                 }
 
                                 @Override
@@ -206,46 +128,101 @@ public class AccountRemovalWorker extends Worker {
                                 }
                             });
                 } else {
-                    userUtils.deleteUser(userEntity.getId())
-                            .subscribe(new CompletableObserver() {
-                                @Override
-                                public void onSubscribe(Disposable d) {
+                    deleteUser(userEntity);
+                }
+            } catch (IOException e) {
+                Log.d(TAG, "Something went wrong while removing job at parsing PushConfigurationState");
+                deleteUser(userEntity);
+            }
+        }
 
-                                }
+        return Result.success();
+    }
 
-                                @Override
-                                public void onComplete() {
+    private void unregisterDeviceForNotificationWithProxy(HashMap<String, String> queryMap, UserEntity userEntity) {
+        ncApi.unregisterDeviceForNotificationsWithProxy
+                (ApiUtils.getUrlPushProxy(), queryMap)
+                .subscribe(new Observer<Void>() {
+                    @Override
+                    public void onSubscribe(Disposable d) {
+
+                    }
+
+                    @Override
+                    public void onNext(Void aVoid) {
+                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+                            String groupName = String.format(getApplicationContext().getResources()
+                                    .getString(R.string
+                                            .nc_notification_channel), userEntity.getUserId(), userEntity.getBaseUrl());
+                            CRC32 crc32 = new CRC32();
+                            crc32.update(groupName.getBytes());
+                            NotificationManager notificationManager =
+                                    (NotificationManager) getApplicationContext().getSystemService
+                                            (Context.NOTIFICATION_SERVICE);
+
+                            if (notificationManager != null) {
+                                notificationManager.deleteNotificationChannelGroup(Long
+                                        .toString(crc32.getValue()));
+                            }
+                        }
+                        WebSocketConnectionHelper.deleteExternalSignalingInstanceForUserEntity(userEntity.getId());
+                        deleteAllEntriesForAccountIdentifier(userEntity);
+                    }
 
-                                }
+                    @Override
+                    public void onError(Throwable e) {
+                        Log.e(TAG, "error while trying to unregister Device For Notification With Proxy", e);
+                    }
 
-                                @Override
-                                public void onError(Throwable e) {
+                    @Override
+                    public void onComplete() {
 
-                                }
-                            });
-                }
-            } catch (IOException e) {
-                Log.d(TAG, "Something went wrong while removing job at parsing PushConfigurationState");
-                userUtils.deleteUser(userEntity.getId())
-                        .subscribe(new CompletableObserver() {
-                            @Override
-                            public void onSubscribe(Disposable d) {
+                    }
+                });
+    }
 
-                            }
+    private void deleteAllEntriesForAccountIdentifier(UserEntity userEntity) {
+        arbitraryStorageUtils.deleteAllEntriesForAccountIdentifier(userEntity.getId()).subscribe(new Observer() {
+            @Override
+            public void onSubscribe(Disposable d) {
 
-                            @Override
-                            public void onComplete() {
+            }
 
-                            }
+            @Override
+            public void onNext(Object o) {
+                deleteUser(userEntity);
+            }
 
-                            @Override
-                            public void onError(Throwable e) {
+            @Override
+            public void onError(Throwable e) {
+                Log.e(TAG, "error while trying to delete All Entries For Account Identifier", e);
+            }
+
+            @Override
+            public void onComplete() {
 
-                            }
-                        });
             }
-        }
+        });
+    }
 
-        return Result.success();
+    private void deleteUser(UserEntity userEntity) {
+        String username = userEntity.getUsername();
+        userUtils.deleteUser(userEntity.getId())
+                .subscribe(new CompletableObserver() {
+                    @Override
+                    public void onSubscribe(Disposable d) {
+
+                    }
+
+                    @Override
+                    public void onComplete() {
+                        Log.d(TAG, "deleted user: " + username);
+                    }
+
+                    @Override
+                    public void onError(Throwable e) {
+                        Log.e(TAG, "error while trying to delete user", e);
+                    }
+                });
     }
 }

+ 2 - 0
app/src/main/res/values/strings.xml

@@ -409,4 +409,6 @@
     <string name="failed_to_save">Failed to save %1$s</string>
     <string name="selected_list_item">selected</string>
     <string name="filename_progress">%1$s (%2$d)</string>
+    <string name="nc_dialog_invalid_password">Invalid password</string>
+    <string name="nc_dialog_reauth_or_delete">Do you want to reauthorize or delete this account?</string>
 </resources>