mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-20 11:08:31 +00:00
Enforce correct permissions when pinning messages.
This commit is contained in:
committed by
jeffrey-signal
parent
40008bddc7
commit
44ec15c0e0
@@ -39,9 +39,10 @@ public final class ConversationReactionDelegate {
|
|||||||
@NonNull Recipient conversationRecipient,
|
@NonNull Recipient conversationRecipient,
|
||||||
@NonNull ConversationMessage conversationMessage,
|
@NonNull ConversationMessage conversationMessage,
|
||||||
boolean isNonAdminInAnnouncementGroup,
|
boolean isNonAdminInAnnouncementGroup,
|
||||||
@NonNull SelectedConversationModel selectedConversationModel)
|
@NonNull SelectedConversationModel selectedConversationModel,
|
||||||
|
boolean canEditGroupInfo)
|
||||||
{
|
{
|
||||||
resolveOverlay().show(activity, conversationRecipient, conversationMessage, lastSeenDownPoint, isNonAdminInAnnouncementGroup, selectedConversationModel);
|
resolveOverlay().show(activity, conversationRecipient, conversationMessage, lastSeenDownPoint, isNonAdminInAnnouncementGroup, selectedConversationModel, canEditGroupInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hide() {
|
public void hide() {
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ public final class ConversationReactionOverlay extends FrameLayout {
|
|||||||
private SelectedConversationModel selectedConversationModel;
|
private SelectedConversationModel selectedConversationModel;
|
||||||
private OverlayState overlayState = OverlayState.HIDDEN;
|
private OverlayState overlayState = OverlayState.HIDDEN;
|
||||||
private boolean isNonAdminInAnnouncementGroup;
|
private boolean isNonAdminInAnnouncementGroup;
|
||||||
|
private boolean canEditGroupInfo;
|
||||||
|
|
||||||
private boolean downIsOurs;
|
private boolean downIsOurs;
|
||||||
private int selected = -1;
|
private int selected = -1;
|
||||||
@@ -144,7 +145,8 @@ public final class ConversationReactionOverlay extends FrameLayout {
|
|||||||
@NonNull ConversationMessage conversationMessage,
|
@NonNull ConversationMessage conversationMessage,
|
||||||
@NonNull PointF lastSeenDownPoint,
|
@NonNull PointF lastSeenDownPoint,
|
||||||
boolean isNonAdminInAnnouncementGroup,
|
boolean isNonAdminInAnnouncementGroup,
|
||||||
@NonNull SelectedConversationModel selectedConversationModel)
|
@NonNull SelectedConversationModel selectedConversationModel,
|
||||||
|
boolean canEditGroupInfo)
|
||||||
{
|
{
|
||||||
if (overlayState != OverlayState.HIDDEN) {
|
if (overlayState != OverlayState.HIDDEN) {
|
||||||
return;
|
return;
|
||||||
@@ -154,6 +156,7 @@ public final class ConversationReactionOverlay extends FrameLayout {
|
|||||||
this.conversationRecipient = conversationRecipient;
|
this.conversationRecipient = conversationRecipient;
|
||||||
this.selectedConversationModel = selectedConversationModel;
|
this.selectedConversationModel = selectedConversationModel;
|
||||||
this.isNonAdminInAnnouncementGroup = isNonAdminInAnnouncementGroup;
|
this.isNonAdminInAnnouncementGroup = isNonAdminInAnnouncementGroup;
|
||||||
|
this.canEditGroupInfo = canEditGroupInfo;
|
||||||
overlayState = OverlayState.UNINITAILIZED;
|
overlayState = OverlayState.UNINITAILIZED;
|
||||||
selected = -1;
|
selected = -1;
|
||||||
|
|
||||||
@@ -674,7 +677,7 @@ public final class ConversationReactionOverlay extends FrameLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private @NonNull List<ActionItem> getMenuActionItems(@NonNull ConversationMessage conversationMessage) {
|
private @NonNull List<ActionItem> getMenuActionItems(@NonNull ConversationMessage conversationMessage) {
|
||||||
MenuState menuState = MenuState.getMenuState(conversationRecipient, conversationMessage.getMultiselectCollection().toSet(), false, isNonAdminInAnnouncementGroup);
|
MenuState menuState = MenuState.getMenuState(conversationRecipient, conversationMessage.getMultiselectCollection().toSet(), false, isNonAdminInAnnouncementGroup, canEditGroupInfo);
|
||||||
|
|
||||||
List<ActionItem> items = new ArrayList<>();
|
List<ActionItem> items = new ArrayList<>();
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,8 @@ public final class MenuState {
|
|||||||
public static MenuState getMenuState(@NonNull Recipient conversationRecipient,
|
public static MenuState getMenuState(@NonNull Recipient conversationRecipient,
|
||||||
@NonNull Set<MultiselectPart> selectedParts,
|
@NonNull Set<MultiselectPart> selectedParts,
|
||||||
boolean shouldShowMessageRequest,
|
boolean shouldShowMessageRequest,
|
||||||
boolean isNonAdminInAnnouncementGroup)
|
boolean isNonAdminInAnnouncementGroup,
|
||||||
|
boolean canEditGroupInfo)
|
||||||
{
|
{
|
||||||
|
|
||||||
Builder builder = new Builder();
|
Builder builder = new Builder();
|
||||||
@@ -170,11 +171,11 @@ public final class MenuState {
|
|||||||
hasPollTerminate = true;
|
hasPollTerminate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RemoteConfig.sendPinnedMessages() && !messageRecord.isPending() && messageRecord.getPinnedUntil() == 0 && !conversationRecipient.isReleaseNotes()) { // TODO(michelle): Also check against group permissions
|
if (RemoteConfig.sendPinnedMessages() && !messageRecord.isPending() && messageRecord.getPinnedUntil() == 0 && !conversationRecipient.isReleaseNotes() && canEditGroupInfo) {
|
||||||
canPinMessage = true;
|
canPinMessage = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RemoteConfig.sendPinnedMessages() && messageRecord.getPinnedUntil() != 0 && !conversationRecipient.isReleaseNotes()) { // TODO(michelle): Also check against group permissions
|
if (RemoteConfig.sendPinnedMessages() && messageRecord.getPinnedUntil() != 0 && !conversationRecipient.isReleaseNotes() && canEditGroupInfo) {
|
||||||
canUnpinMessage = true;
|
canUnpinMessage = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import org.thoughtcrime.securesms.recipients.RecipientId
|
|||||||
import org.thoughtcrime.securesms.util.BottomSheetUtil
|
import org.thoughtcrime.securesms.util.BottomSheetUtil
|
||||||
import org.thoughtcrime.securesms.util.StickyHeaderDecoration
|
import org.thoughtcrime.securesms.util.StickyHeaderDecoration
|
||||||
import org.thoughtcrime.securesms.util.fragments.findListener
|
import org.thoughtcrime.securesms.util.fragments.findListener
|
||||||
|
import org.thoughtcrime.securesms.util.visible
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -110,12 +111,13 @@ class PinnedMessagesBottomSheet : FixedRoundedCornerBottomSheetDialogFragment()
|
|||||||
|
|
||||||
initializeGiphyMp4(view.findViewById(R.id.video_container)!!, list)
|
initializeGiphyMp4(view.findViewById(R.id.video_container)!!, list)
|
||||||
|
|
||||||
// TODO(michelle): Hide if not allowed to unpin / Check with design about a confirmation dialog here
|
// TODO(michelle): Check with design about a confirmation dialog here
|
||||||
val unpinAll = view.findViewById<TextView>(R.id.unpin_all)
|
val unpinAll = view.findViewById<TextView>(R.id.unpin_all)
|
||||||
unpinAll.setOnClickListener {
|
unpinAll.setOnClickListener {
|
||||||
viewModel.unpinMessage()
|
viewModel.unpinMessage()
|
||||||
dismissAllowingStateLoss()
|
dismissAllowingStateLoss()
|
||||||
}
|
}
|
||||||
|
unpinAll.visible = requireArguments().getBoolean(KEY_CAN_UNPIN)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initializeGiphyMp4(videoContainer: ViewGroup, list: RecyclerView): GiphyMp4ProjectionRecycler {
|
private fun initializeGiphyMp4(videoContainer: ViewGroup, list: RecyclerView): GiphyMp4ProjectionRecycler {
|
||||||
@@ -271,12 +273,14 @@ class PinnedMessagesBottomSheet : FixedRoundedCornerBottomSheetDialogFragment()
|
|||||||
|
|
||||||
private const val KEY_THREAD_ID = "thread_id"
|
private const val KEY_THREAD_ID = "thread_id"
|
||||||
private const val KEY_CONVERSATION_RECIPIENT_ID = "conversation_recipient_id"
|
private const val KEY_CONVERSATION_RECIPIENT_ID = "conversation_recipient_id"
|
||||||
|
private const val KEY_CAN_UNPIN = "can_unpin"
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun show(fragmentManager: FragmentManager, threadId: Long, conversationRecipientId: RecipientId) {
|
fun show(fragmentManager: FragmentManager, threadId: Long, conversationRecipientId: RecipientId, canUnpin: Boolean) {
|
||||||
val args = Bundle().apply {
|
val args = Bundle().apply {
|
||||||
putLong(KEY_THREAD_ID, threadId)
|
putLong(KEY_THREAD_ID, threadId)
|
||||||
putString(KEY_CONVERSATION_RECIPIENT_ID, conversationRecipientId.serialize())
|
putString(KEY_CONVERSATION_RECIPIENT_ID, conversationRecipientId.serialize())
|
||||||
|
putBoolean(KEY_CAN_UNPIN, canUnpin)
|
||||||
}
|
}
|
||||||
|
|
||||||
val fragment = PinnedMessagesBottomSheet().apply {
|
val fragment = PinnedMessagesBottomSheet().apply {
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ class ConversationBannerView @JvmOverloads constructor(
|
|||||||
hide(voiceNotePlayerStub)
|
hide(voiceNotePlayerStub)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showPinnedMessageStub(messages: List<ConversationMessage>) {
|
fun showPinnedMessageStub(messages: List<ConversationMessage>, canUnpin: Boolean) {
|
||||||
show(
|
show(
|
||||||
stub = pinnedMessageStub
|
stub = pinnedMessageStub
|
||||||
) {
|
) {
|
||||||
@@ -142,6 +142,7 @@ class ConversationBannerView @JvmOverloads constructor(
|
|||||||
SignalTheme(isDarkMode = DynamicTheme.isDarkTheme(context)) {
|
SignalTheme(isDarkMode = DynamicTheme.isDarkTheme(context)) {
|
||||||
PinnedMessagesBanner(
|
PinnedMessagesBanner(
|
||||||
messages = messages,
|
messages = messages,
|
||||||
|
canUnpin = canUnpin,
|
||||||
onUnpinMessage = { messageId -> listener?.onUnpinMessage(messageId) },
|
onUnpinMessage = { messageId -> listener?.onUnpinMessage(messageId) },
|
||||||
onGoToMessage = { messageId -> listener?.onGoToMessage(messageId) },
|
onGoToMessage = { messageId -> listener?.onGoToMessage(messageId) },
|
||||||
onViewAllMessages = { listener?.onViewAllMessages() }
|
onViewAllMessages = { listener?.onViewAllMessages() }
|
||||||
|
|||||||
@@ -1336,7 +1336,7 @@ class ConversationFragment :
|
|||||||
|
|
||||||
private fun presentPinnedMessage(pinnedMessages: List<ConversationMessage>) {
|
private fun presentPinnedMessage(pinnedMessages: List<ConversationMessage>) {
|
||||||
if (pinnedMessages.isNotEmpty()) {
|
if (pinnedMessages.isNotEmpty()) {
|
||||||
binding.conversationBanner.showPinnedMessageStub(pinnedMessages)
|
binding.conversationBanner.showPinnedMessageStub(messages = pinnedMessages, canUnpin = conversationGroupViewModel.canEditGroupInfo())
|
||||||
} else {
|
} else {
|
||||||
binding.conversationBanner.hidePinnedMessageStub()
|
binding.conversationBanner.hidePinnedMessageStub()
|
||||||
}
|
}
|
||||||
@@ -2311,7 +2311,8 @@ class ConversationFragment :
|
|||||||
recipient,
|
recipient,
|
||||||
selectedParts,
|
selectedParts,
|
||||||
viewModel.hasMessageRequestState,
|
viewModel.hasMessageRequestState,
|
||||||
conversationGroupViewModel.isNonAdminInAnnouncementGroup()
|
conversationGroupViewModel.isNonAdminInAnnouncementGroup(),
|
||||||
|
conversationGroupViewModel.canEditGroupInfo()
|
||||||
)
|
)
|
||||||
|
|
||||||
val items = arrayListOf<ActionItem>()
|
val items = arrayListOf<ActionItem>()
|
||||||
@@ -2458,7 +2459,7 @@ class ConversationFragment :
|
|||||||
) {
|
) {
|
||||||
reactionDelegate.setOnActionSelectedListener(onActionSelectedListener)
|
reactionDelegate.setOnActionSelectedListener(onActionSelectedListener)
|
||||||
reactionDelegate.setOnHideListener(onHideListener)
|
reactionDelegate.setOnHideListener(onHideListener)
|
||||||
reactionDelegate.show(requireActivity(), viewModel.recipientSnapshot!!, conversationMessage, conversationGroupViewModel.isNonAdminInAnnouncementGroup(), selectedConversationModel)
|
reactionDelegate.show(requireActivity(), viewModel.recipientSnapshot!!, conversationMessage, conversationGroupViewModel.isNonAdminInAnnouncementGroup(), selectedConversationModel, conversationGroupViewModel.canEditGroupInfo())
|
||||||
viewModel.setIsReactionDelegateShowing(true)
|
viewModel.setIsReactionDelegateShowing(true)
|
||||||
composeText.clearFocus()
|
composeText.clearFocus()
|
||||||
}
|
}
|
||||||
@@ -4232,8 +4233,9 @@ class ConversationFragment :
|
|||||||
override fun onViewAllMessages() {
|
override fun onViewAllMessages() {
|
||||||
PinnedMessagesBottomSheet.show(
|
PinnedMessagesBottomSheet.show(
|
||||||
childFragmentManager,
|
childFragmentManager,
|
||||||
args.threadId,
|
threadId = args.threadId,
|
||||||
viewModel.recipientSnapshot?.id!!
|
conversationRecipientId = viewModel.recipientSnapshot?.id!!,
|
||||||
|
canUnpin = conversationGroupViewModel.canEditGroupInfo()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ import kotlin.jvm.optionals.getOrDefault
|
|||||||
@Composable
|
@Composable
|
||||||
fun PinnedMessagesBanner(
|
fun PinnedMessagesBanner(
|
||||||
messages: List<ConversationMessage> = emptyList(),
|
messages: List<ConversationMessage> = emptyList(),
|
||||||
|
canUnpin: Boolean,
|
||||||
onUnpinMessage: (Long) -> Unit = {},
|
onUnpinMessage: (Long) -> Unit = {},
|
||||||
onGoToMessage: (Long) -> Unit = {},
|
onGoToMessage: (Long) -> Unit = {},
|
||||||
onViewAllMessages: () -> Unit = {}
|
onViewAllMessages: () -> Unit = {}
|
||||||
@@ -150,7 +151,9 @@ fun PinnedMessagesBanner(
|
|||||||
|
|
||||||
DropdownMenus.Menu(controller = menuController, offsetX = 2.dp, offsetY = 16.dp) { menuController ->
|
DropdownMenus.Menu(controller = menuController, offsetX = 2.dp, offsetY = 16.dp) { menuController ->
|
||||||
Column {
|
Column {
|
||||||
DropdownMenus.ItemWithIcon(menuController, R.drawable.symbol_pin_slash_24, R.string.PinnedMessage__unpin_message) { onUnpinMessage(message.id) }
|
if (canUnpin) {
|
||||||
|
DropdownMenus.ItemWithIcon(menuController, R.drawable.symbol_pin_slash_24, R.string.PinnedMessage__unpin_message) { onUnpinMessage(message.id) }
|
||||||
|
}
|
||||||
DropdownMenus.ItemWithIcon(menuController, R.drawable.symbol_chat_24, R.string.PinnedMessage__go_to_message) { onGoToMessage(message.id) }
|
DropdownMenus.ItemWithIcon(menuController, R.drawable.symbol_chat_24, R.string.PinnedMessage__go_to_message) { onGoToMessage(message.id) }
|
||||||
DropdownMenus.ItemWithIcon(menuController, R.drawable.symbol_list_bullet_24, R.string.PinnedMessage__view_all_messages) { onViewAllMessages() }
|
DropdownMenus.ItemWithIcon(menuController, R.drawable.symbol_list_bullet_24, R.string.PinnedMessage__view_all_messages) { onViewAllMessages() }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,5 +8,6 @@ import org.thoughtcrime.securesms.database.GroupTable
|
|||||||
*/
|
*/
|
||||||
data class ConversationGroupMemberLevel(
|
data class ConversationGroupMemberLevel(
|
||||||
val groupTableMemberLevel: GroupTable.MemberLevel,
|
val groupTableMemberLevel: GroupTable.MemberLevel,
|
||||||
val isAnnouncementGroup: Boolean
|
val isAnnouncementGroup: Boolean,
|
||||||
|
val allMembersCanEditGroupInfo: Boolean
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import org.thoughtcrime.securesms.conversation.v2.ConversationRecipientRepositor
|
|||||||
import org.thoughtcrime.securesms.database.GroupTable
|
import org.thoughtcrime.securesms.database.GroupTable
|
||||||
import org.thoughtcrime.securesms.database.model.GroupRecord
|
import org.thoughtcrime.securesms.database.model.GroupRecord
|
||||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||||
|
import org.thoughtcrime.securesms.groups.GroupAccessControl
|
||||||
import org.thoughtcrime.securesms.groups.GroupId
|
import org.thoughtcrime.securesms.groups.GroupId
|
||||||
import org.thoughtcrime.securesms.groups.ui.GroupChangeFailureReason
|
import org.thoughtcrime.securesms.groups.ui.GroupChangeFailureReason
|
||||||
import org.thoughtcrime.securesms.groups.v2.GroupBlockJoinRequestResult
|
import org.thoughtcrime.securesms.groups.v2.GroupBlockJoinRequestResult
|
||||||
@@ -53,7 +54,7 @@ class ConversationGroupViewModel(
|
|||||||
init {
|
init {
|
||||||
disposables += _groupRecord.subscribe { groupRecord ->
|
disposables += _groupRecord.subscribe { groupRecord ->
|
||||||
_groupActiveState.onNext(ConversationGroupActiveState(groupRecord.isActive, groupRecord.isV2Group))
|
_groupActiveState.onNext(ConversationGroupActiveState(groupRecord.isActive, groupRecord.isV2Group))
|
||||||
_memberLevel.onNext(ConversationGroupMemberLevel(groupRecord.memberLevel(Recipient.self()), groupRecord.isAnnouncementGroup))
|
_memberLevel.onNext(ConversationGroupMemberLevel(groupRecord.memberLevel(Recipient.self()), groupRecord.isAnnouncementGroup, groupRecord.attributesAccessControl == GroupAccessControl.ALL_MEMBERS))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,6 +67,11 @@ class ConversationGroupViewModel(
|
|||||||
return memberLevel.groupTableMemberLevel != GroupTable.MemberLevel.ADMINISTRATOR && memberLevel.isAnnouncementGroup
|
return memberLevel.groupTableMemberLevel != GroupTable.MemberLevel.ADMINISTRATOR && memberLevel.isAnnouncementGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun canEditGroupInfo(): Boolean {
|
||||||
|
val memberLevel = _memberLevel.value ?: return true
|
||||||
|
return memberLevel.groupTableMemberLevel == GroupTable.MemberLevel.ADMINISTRATOR || memberLevel.allMembersCanEditGroupInfo
|
||||||
|
}
|
||||||
|
|
||||||
fun blockJoinRequests(recipient: Recipient): Single<GroupBlockJoinRequestResult> {
|
fun blockJoinRequests(recipient: Recipient): Single<GroupBlockJoinRequestResult> {
|
||||||
return _groupRecord
|
return _groupRecord
|
||||||
.firstOrError()
|
.firstOrError()
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import org.thoughtcrime.securesms.database.model.GroupRecord;
|
|||||||
import org.thoughtcrime.securesms.database.model.MessageId;
|
import org.thoughtcrime.securesms.database.model.MessageId;
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||||
import org.thoughtcrime.securesms.dependencies.AppDependencies;
|
import org.thoughtcrime.securesms.dependencies.AppDependencies;
|
||||||
|
import org.thoughtcrime.securesms.groups.GroupAccessControl;
|
||||||
import org.thoughtcrime.securesms.groups.GroupId;
|
import org.thoughtcrime.securesms.groups.GroupId;
|
||||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||||
import org.thoughtcrime.securesms.jobmanager.JobLogger;
|
import org.thoughtcrime.securesms.jobmanager.JobLogger;
|
||||||
@@ -348,7 +349,9 @@ public final class PushGroupSendJob extends PushSendJob {
|
|||||||
} else {
|
} else {
|
||||||
Optional<GroupRecord> groupRecord = SignalDatabase.groups().getGroup(groupRecipient.requireGroupId());
|
Optional<GroupRecord> groupRecord = SignalDatabase.groups().getGroup(groupRecipient.requireGroupId());
|
||||||
|
|
||||||
if (groupRecord.isPresent() && groupRecord.get().isAnnouncementGroup() && !groupRecord.get().isAdmin(Recipient.self())) {
|
if (pinnedMessage != null && groupRecord.isPresent() && groupRecord.get().getAttributesAccessControl() == GroupAccessControl.ONLY_ADMINS && !groupRecord.get().isAdmin(Recipient.self())) {
|
||||||
|
throw new UndeliverableMessageException("Non-admins cannot pin messages in this group!");
|
||||||
|
} else if (pinnedMessage == null && groupRecord.isPresent() && groupRecord.get().isAnnouncementGroup() && !groupRecord.get().isAdmin(Recipient.self())) {
|
||||||
throw new UndeliverableMessageException("Non-admins cannot send messages in announcement groups!");
|
throw new UndeliverableMessageException("Non-admins cannot send messages in announcement groups!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.jobs
|
|||||||
import org.signal.core.util.logging.Log
|
import org.signal.core.util.logging.Log
|
||||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||||
import org.thoughtcrime.securesms.database.model.MessageId
|
import org.thoughtcrime.securesms.database.model.MessageId
|
||||||
|
import org.thoughtcrime.securesms.groups.GroupAccessControl
|
||||||
import org.thoughtcrime.securesms.groups.GroupId
|
import org.thoughtcrime.securesms.groups.GroupId
|
||||||
import org.thoughtcrime.securesms.jobmanager.Job
|
import org.thoughtcrime.securesms.jobmanager.Job
|
||||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint
|
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint
|
||||||
@@ -10,6 +11,7 @@ import org.thoughtcrime.securesms.jobs.protos.UnpinJobData
|
|||||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||||
import org.thoughtcrime.securesms.messages.GroupSendUtil
|
import org.thoughtcrime.securesms.messages.GroupSendUtil
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient
|
import org.thoughtcrime.securesms.recipients.Recipient
|
||||||
|
import org.thoughtcrime.securesms.recipients.Recipient.Companion.self
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientUtil
|
import org.thoughtcrime.securesms.recipients.RecipientUtil
|
||||||
import org.thoughtcrime.securesms.util.GroupUtil
|
import org.thoughtcrime.securesms.util.GroupUtil
|
||||||
@@ -97,6 +99,14 @@ class UnpinMessageJob(
|
|||||||
return Result.failure()
|
return Result.failure()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (conversationRecipient.isPushV2Group) {
|
||||||
|
val groupRecord = SignalDatabase.groups.getGroup(conversationRecipient.id)
|
||||||
|
if (groupRecord.isPresent && groupRecord.get().attributesAccessControl == GroupAccessControl.ONLY_ADMINS && !groupRecord.get().isAdmin(self())) {
|
||||||
|
Log.w(TAG, "Non-admins cannot send unpin messages to group.")
|
||||||
|
return Result.failure()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val targetSentTimestamp = message.dateSent
|
val targetSentTimestamp = message.dateSent
|
||||||
|
|
||||||
val recipients = Recipient.resolvedList(recipientIds.filter { it != Recipient.self().id.toLong() }.map { RecipientId.from(it) })
|
val recipients = Recipient.resolvedList(recipientIds.filter { it != Recipient.self().id.toLong() }.map { RecipientId.from(it) })
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ import org.thoughtcrime.securesms.database.model.databaseprotos.PollTerminate
|
|||||||
import org.thoughtcrime.securesms.database.model.toBodyRangeList
|
import org.thoughtcrime.securesms.database.model.toBodyRangeList
|
||||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||||
import org.thoughtcrime.securesms.groups.BadGroupIdException
|
import org.thoughtcrime.securesms.groups.BadGroupIdException
|
||||||
|
import org.thoughtcrime.securesms.groups.GroupAccessControl
|
||||||
import org.thoughtcrime.securesms.groups.GroupId
|
import org.thoughtcrime.securesms.groups.GroupId
|
||||||
import org.thoughtcrime.securesms.jobs.AttachmentDownloadJob
|
import org.thoughtcrime.securesms.jobs.AttachmentDownloadJob
|
||||||
import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob
|
import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob
|
||||||
@@ -1305,6 +1306,10 @@ object DataMessageProcessor {
|
|||||||
warn(envelope.timestamp!!, "[handlePinMessage] Sender is not in the group! timestamp: ${pinMessage.targetSentTimestamp}")
|
warn(envelope.timestamp!!, "[handlePinMessage] Sender is not in the group! timestamp: ${pinMessage.targetSentTimestamp}")
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
if (groupRecord != null && groupRecord.attributesAccessControl == GroupAccessControl.ONLY_ADMINS && !groupRecord.isAdmin(senderRecipient)) {
|
||||||
|
warn(envelope.timestamp!!, "[handlePinMessage] Sender needs to be an admin! timestamp: ${pinMessage.targetSentTimestamp}")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
if (groupRecord == null && senderRecipient.id != threadRecipient.id && Recipient.self().id != senderRecipient.id) {
|
if (groupRecord == null && senderRecipient.id != threadRecipient.id && Recipient.self().id != senderRecipient.id) {
|
||||||
warn(envelope.timestamp!!, "[handlePinMessage] Sender is not a part of the 1:1 thread! timestamp: ${pinMessage.targetSentTimestamp}")
|
warn(envelope.timestamp!!, "[handlePinMessage] Sender is not a part of the 1:1 thread! timestamp: ${pinMessage.targetSentTimestamp}")
|
||||||
@@ -1384,6 +1389,10 @@ object DataMessageProcessor {
|
|||||||
warn(envelope.timestamp!!, "[handleUnpinMessage] Sender is not in the group! timestamp: ${unpinMessage.targetSentTimestamp}")
|
warn(envelope.timestamp!!, "[handleUnpinMessage] Sender is not in the group! timestamp: ${unpinMessage.targetSentTimestamp}")
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
if (groupRecord != null && groupRecord.attributesAccessControl == GroupAccessControl.ONLY_ADMINS && !groupRecord.isAdmin(senderRecipient)) {
|
||||||
|
warn(envelope.timestamp!!, "[handleUnpinMessage] Sender needs to be an admin! timestamp: ${unpinMessage.targetSentTimestamp}")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
if (groupRecord == null && senderRecipient.id != threadRecipient.id && Recipient.self().id != senderRecipient.id) {
|
if (groupRecord == null && senderRecipient.id != threadRecipient.id && Recipient.self().id != senderRecipient.id) {
|
||||||
warn(envelope.timestamp!!, "[handleUnpinMessage] Sender is not a part of the 1:1 thread! timestamp: ${unpinMessage.targetSentTimestamp}")
|
warn(envelope.timestamp!!, "[handleUnpinMessage] Sender is not a part of the 1:1 thread! timestamp: ${unpinMessage.targetSentTimestamp}")
|
||||||
|
|||||||
Reference in New Issue
Block a user