]> nmode's Git Repositories - signal-cli/blob - lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV2.java
6a8de5924e8425d2a5901e92d0558674d98dec02
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / storage / groups / GroupInfoV2.java
1 package org.asamk.signal.manager.storage.groups;
2
3 import org.asamk.signal.manager.api.GroupIdV2;
4 import org.asamk.signal.manager.api.GroupInviteLinkUrl;
5 import org.asamk.signal.manager.api.GroupPermission;
6 import org.asamk.signal.manager.storage.recipients.RecipientAddress;
7 import org.asamk.signal.manager.storage.recipients.RecipientId;
8 import org.asamk.signal.manager.storage.recipients.RecipientResolver;
9 import org.signal.libsignal.zkgroup.groups.GroupMasterKey;
10 import org.signal.storageservice.protos.groups.AccessControl;
11 import org.signal.storageservice.protos.groups.Member;
12 import org.signal.storageservice.protos.groups.local.DecryptedGroup;
13 import org.signal.storageservice.protos.groups.local.EnabledState;
14 import org.whispersystems.signalservice.api.push.DistributionId;
15 import org.whispersystems.signalservice.api.push.ServiceId;
16
17 import java.util.Set;
18 import java.util.stream.Collectors;
19
20 public final class GroupInfoV2 extends GroupInfo {
21
22 private final GroupIdV2 groupId;
23 private final GroupMasterKey masterKey;
24 private DistributionId distributionId;
25 private boolean blocked;
26 private DecryptedGroup group;
27 private boolean permissionDenied;
28
29 private final RecipientResolver recipientResolver;
30
31 public GroupInfoV2(
32 final GroupIdV2 groupId, final GroupMasterKey masterKey, final RecipientResolver recipientResolver
33 ) {
34 this.groupId = groupId;
35 this.masterKey = masterKey;
36 this.distributionId = DistributionId.create();
37 this.recipientResolver = recipientResolver;
38 }
39
40 public GroupInfoV2(
41 final GroupIdV2 groupId,
42 final GroupMasterKey masterKey,
43 final DecryptedGroup group,
44 final DistributionId distributionId,
45 final boolean blocked,
46 final boolean permissionDenied,
47 final RecipientResolver recipientResolver
48 ) {
49 this.groupId = groupId;
50 this.masterKey = masterKey;
51 this.group = group;
52 this.distributionId = distributionId;
53 this.blocked = blocked;
54 this.permissionDenied = permissionDenied;
55 this.recipientResolver = recipientResolver;
56 }
57
58 @Override
59 public GroupIdV2 getGroupId() {
60 return groupId;
61 }
62
63 public GroupMasterKey getMasterKey() {
64 return masterKey;
65 }
66
67 public DistributionId getDistributionId() {
68 return distributionId;
69 }
70
71 public void setGroup(final DecryptedGroup group) {
72 if (group != null) {
73 this.permissionDenied = false;
74 }
75 this.group = group;
76 }
77
78 public DecryptedGroup getGroup() {
79 return group;
80 }
81
82 @Override
83 public String getTitle() {
84 if (this.group == null) {
85 return null;
86 }
87 return this.group.getTitle();
88 }
89
90 @Override
91 public String getDescription() {
92 if (this.group == null) {
93 return null;
94 }
95 return this.group.getDescription();
96 }
97
98 @Override
99 public GroupInviteLinkUrl getGroupInviteLink() {
100 if (this.group == null || this.group.getInviteLinkPassword().isEmpty() || (
101 this.group.getAccessControl().getAddFromInviteLink() != AccessControl.AccessRequired.ANY
102 && this.group.getAccessControl().getAddFromInviteLink()
103 != AccessControl.AccessRequired.ADMINISTRATOR
104 )) {
105 return null;
106 }
107
108 return GroupInviteLinkUrl.forGroup(masterKey, group);
109 }
110
111 @Override
112 public Set<RecipientId> getMembers() {
113 if (this.group == null) {
114 return Set.of();
115 }
116 return group.getMembersList()
117 .stream()
118 .map(m -> ServiceId.parseOrThrow(m.getAciBytes()))
119 .map(recipientResolver::resolveRecipient)
120 .collect(Collectors.toSet());
121 }
122
123 @Override
124 public Set<RecipientId> getBannedMembers() {
125 if (this.group == null) {
126 return Set.of();
127 }
128 return group.getBannedMembersList()
129 .stream()
130 .map(m -> ServiceId.parseOrThrow(m.getServiceIdBytes()))
131 .map(recipientResolver::resolveRecipient)
132 .collect(Collectors.toSet());
133 }
134
135 @Override
136 public Set<RecipientId> getPendingMembers() {
137 if (this.group == null) {
138 return Set.of();
139 }
140 return group.getPendingMembersList()
141 .stream()
142 .map(m -> ServiceId.parseOrThrow(m.getServiceIdBytes()))
143 .map(recipientResolver::resolveRecipient)
144 .collect(Collectors.toSet());
145 }
146
147 @Override
148 public Set<RecipientId> getRequestingMembers() {
149 if (this.group == null) {
150 return Set.of();
151 }
152 return group.getRequestingMembersList()
153 .stream()
154 .map(m -> ServiceId.parseOrThrow(m.getAciBytes()))
155 .map(recipientResolver::resolveRecipient)
156 .collect(Collectors.toSet());
157 }
158
159 @Override
160 public Set<RecipientId> getAdminMembers() {
161 if (this.group == null) {
162 return Set.of();
163 }
164 return group.getMembersList()
165 .stream()
166 .filter(m -> m.getRole() == Member.Role.ADMINISTRATOR)
167 .map(m -> new RecipientAddress(ServiceId.ACI.parseOrNull(m.getAciBytes()),
168 ServiceId.PNI.parseOrNull(m.getPniBytes()),
169 null))
170 .map(recipientResolver::resolveRecipient)
171 .collect(Collectors.toSet());
172 }
173
174 @Override
175 public boolean isBlocked() {
176 return blocked;
177 }
178
179 @Override
180 public void setBlocked(final boolean blocked) {
181 this.blocked = blocked;
182 }
183
184 @Override
185 public int getMessageExpirationTimer() {
186 return this.group != null && this.group.hasDisappearingMessagesTimer()
187 ? this.group.getDisappearingMessagesTimer().getDuration()
188 : 0;
189 }
190
191 @Override
192 public boolean isAnnouncementGroup() {
193 return this.group != null && this.group.getIsAnnouncementGroup() == EnabledState.ENABLED;
194 }
195
196 @Override
197 public GroupPermission getPermissionAddMember() {
198 final var accessControl = getAccessControl();
199 return accessControl == null ? GroupPermission.EVERY_MEMBER : toGroupPermission(accessControl.getMembers());
200 }
201
202 @Override
203 public GroupPermission getPermissionEditDetails() {
204 final var accessControl = getAccessControl();
205 return accessControl == null ? GroupPermission.EVERY_MEMBER : toGroupPermission(accessControl.getAttributes());
206 }
207
208 @Override
209 public GroupPermission getPermissionSendMessage() {
210 return isAnnouncementGroup() ? GroupPermission.ONLY_ADMINS : GroupPermission.EVERY_MEMBER;
211 }
212
213 public void setPermissionDenied(final boolean permissionDenied) {
214 this.permissionDenied = permissionDenied;
215 }
216
217 public boolean isPermissionDenied() {
218 return permissionDenied;
219 }
220
221 private AccessControl getAccessControl() {
222 if (this.group == null || !this.group.hasAccessControl()) {
223 return null;
224 }
225
226 return this.group.getAccessControl();
227 }
228
229 private static GroupPermission toGroupPermission(final AccessControl.AccessRequired permission) {
230 return switch (permission) {
231 case ADMINISTRATOR -> GroupPermission.ONLY_ADMINS;
232 default -> GroupPermission.EVERY_MEMBER;
233 };
234 }
235 }