Prevent rejected/kicked group members from joining again via group link.

This commit is contained in:
Cody Henthorne
2022-03-11 10:08:32 -05:00
parent 3503c60fd1
commit eed45b57a1
29 changed files with 687 additions and 149 deletions

View File

@@ -290,6 +290,10 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF
makeGroupAdminButton.setVisibility(adminStatus.isCanMakeAdmin() ? View.VISIBLE : View.GONE);
removeAdminButton.setVisibility(adminStatus.isCanMakeNonAdmin() ? View.VISIBLE : View.GONE);
removeFromGroupButton.setVisibility(adminStatus.isCanRemove() ? View.VISIBLE : View.GONE);
if (adminStatus.isCanRemove()) {
removeFromGroupButton.setOnClickListener(view -> viewModel.onRemoveFromGroupClicked(requireActivity(), adminStatus.isLinkActive(), this::dismiss));
}
});
viewModel.getIdentity().observe(getViewLifecycleOwner(), identityRecord -> {
@@ -319,8 +323,6 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF
makeGroupAdminButton.setOnClickListener(view -> viewModel.onMakeGroupAdminClicked(requireActivity()));
removeAdminButton.setOnClickListener(view -> viewModel.onRemoveGroupAdminClicked(requireActivity()));
removeFromGroupButton.setOnClickListener(view -> viewModel.onRemoveFromGroupClicked(requireActivity(), this::dismiss));
addToGroupButton.setOnClickListener(view -> {
dismiss();
viewModel.onAddToGroupButton(requireActivity());

View File

@@ -77,7 +77,7 @@ final class RecipientDialogRepository {
SimpleTask.run(SignalExecutors.UNBOUNDED,
() -> {
try {
GroupManager.ejectFromGroup(context, Objects.requireNonNull(groupId).requireV2(), Recipient.resolved(recipientId));
GroupManager.ejectAndBanFromGroup(context, Objects.requireNonNull(groupId).requireV2(), Recipient.resolved(recipientId));
return true;
} catch (GroupChangeException | IOException e) {
Log.w(TAG, e);

View File

@@ -15,6 +15,8 @@ import androidx.lifecycle.Transformations;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.signal.core.util.ThreadUtil;
import org.thoughtcrime.securesms.BlockUnblockDialog;
import org.thoughtcrime.securesms.R;
@@ -33,6 +35,7 @@ import org.thoughtcrime.securesms.recipients.RecipientUtil;
import org.thoughtcrime.securesms.util.CommunicationActions;
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
import org.thoughtcrime.securesms.verify.VerifyIdentityActivity;
import org.whispersystems.libsignal.util.Pair;
import java.util.Objects;
@@ -68,20 +71,22 @@ final class RecipientDialogViewModel extends ViewModel {
if (recipientDialogRepository.getGroupId() != null && recipientDialogRepository.getGroupId().isV2() && !recipientIsSelf) {
LiveGroup source = new LiveGroup(recipientDialogRepository.getGroupId());
LiveData<Boolean> localIsAdmin = source.isSelfAdmin();
LiveData<Pair<Boolean, Boolean>> localStatus = LiveDataUtil.combineLatest(source.isSelfAdmin(), Transformations.map(source.getGroupLink(), s -> s == null || s.isEnabled()), Pair::new);
LiveData<GroupDatabase.MemberLevel> recipientMemberLevel = Transformations.switchMap(recipient, source::getMemberLevel);
adminActionStatus = LiveDataUtil.combineLatest(localIsAdmin, recipientMemberLevel,
(localAdmin, memberLevel) -> {
boolean inGroup = memberLevel.isInGroup();
boolean recipientAdmin = memberLevel == GroupDatabase.MemberLevel.ADMINISTRATOR;
adminActionStatus = LiveDataUtil.combineLatest(localStatus, recipientMemberLevel, (statuses, memberLevel) -> {
boolean localAdmin = statuses.first();
boolean isLinkActive = statuses.second();
boolean inGroup = memberLevel.isInGroup();
boolean recipientAdmin = memberLevel == GroupDatabase.MemberLevel.ADMINISTRATOR;
return new AdminActionStatus(inGroup && localAdmin,
inGroup && localAdmin && !recipientAdmin,
inGroup && localAdmin && recipientAdmin);
});
return new AdminActionStatus(inGroup && localAdmin,
inGroup && localAdmin && !recipientAdmin,
inGroup && localAdmin && recipientAdmin,
isLinkActive);
});
} else {
adminActionStatus = new MutableLiveData<>(new AdminActionStatus(false, false, false));
adminActionStatus = new MutableLiveData<>(new AdminActionStatus(false, false, false, false));
}
boolean isSelf = recipientDialogRepository.getRecipientId().equals(Recipient.self().getId());
@@ -164,7 +169,7 @@ final class RecipientDialogViewModel extends ViewModel {
}
void onMakeGroupAdminClicked(@NonNull Activity activity) {
new AlertDialog.Builder(activity)
new MaterialAlertDialogBuilder(activity)
.setMessage(context.getString(R.string.RecipientBottomSheet_s_will_be_able_to_edit_group, Objects.requireNonNull(recipient.getValue()).getDisplayName(context)))
.setPositiveButton(R.string.RecipientBottomSheet_make_admin,
(dialog, which) -> {
@@ -182,7 +187,7 @@ final class RecipientDialogViewModel extends ViewModel {
}
void onRemoveGroupAdminClicked(@NonNull Activity activity) {
new AlertDialog.Builder(activity)
new MaterialAlertDialogBuilder(activity)
.setMessage(context.getString(R.string.RecipientBottomSheet_remove_s_as_group_admin, Objects.requireNonNull(recipient.getValue()).getDisplayName(context)))
.setPositiveButton(R.string.RecipientBottomSheet_remove_as_admin,
(dialog, which) -> {
@@ -199,9 +204,11 @@ final class RecipientDialogViewModel extends ViewModel {
.show();
}
void onRemoveFromGroupClicked(@NonNull Activity activity, @NonNull Runnable onSuccess) {
new AlertDialog.Builder(activity)
.setMessage(context.getString(R.string.RecipientBottomSheet_remove_s_from_the_group, Objects.requireNonNull(recipient.getValue()).getDisplayName(context)))
void onRemoveFromGroupClicked(@NonNull Activity activity, boolean isLinkActive, @NonNull Runnable onSuccess) {
new MaterialAlertDialogBuilder(activity)
.setMessage(context.getString(isLinkActive ? R.string.RecipientBottomSheet_remove_s_from_the_group_they_will_not_be_able_to_rejoin
: R.string.RecipientBottomSheet_remove_s_from_the_group,
Objects.requireNonNull(recipient.getValue()).getDisplayName(context)))
.setPositiveButton(R.string.RecipientBottomSheet_remove,
(dialog, which) -> {
adminActionBusy.setValue(true);
@@ -234,11 +241,13 @@ final class RecipientDialogViewModel extends ViewModel {
private final boolean canRemove;
private final boolean canMakeAdmin;
private final boolean canMakeNonAdmin;
private final boolean isLinkActive;
AdminActionStatus(boolean canRemove, boolean canMakeAdmin, boolean canMakeNonAdmin) {
AdminActionStatus(boolean canRemove, boolean canMakeAdmin, boolean canMakeNonAdmin, boolean isLinkActive) {
this.canRemove = canRemove;
this.canMakeAdmin = canMakeAdmin;
this.canMakeNonAdmin = canMakeNonAdmin;
this.isLinkActive = isLinkActive;
}
boolean isCanRemove() {
@@ -252,6 +261,10 @@ final class RecipientDialogViewModel extends ViewModel {
boolean isCanMakeNonAdmin() {
return canMakeNonAdmin;
}
boolean isLinkActive() {
return isLinkActive;
}
}
public static class Factory implements ViewModelProvider.Factory {