]> nmode's Git Repositories - signal-cli/blob - lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV2.java
c263aa9bcfff7d52d82ee768ae236c3f1a825d53
[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 final 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.title;
88 }
89
90 @Override
91 public String getDescription() {
92 if (this.group == null) {
93 return null;
94 }
95 return this.group.description;
96 }
97
98 @Override
99 public GroupInviteLinkUrl getGroupInviteLink() {
100 if (this.group == null || this.group.inviteLinkPassword.toByteArray().length == 0 || (
101 this.group.accessControl != null
102 && this.group.accessControl.addFromInviteLink != AccessControl.AccessRequired.ANY
103 && this.group.accessControl.addFromInviteLink != 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.members.stream()
117 .map(m -> ServiceId.parseOrThrow(m.aciBytes))
118 .map(recipientResolver::resolveRecipient)
119 .collect(Collectors.toSet());
120 }
121
122 @Override
123 public Set<RecipientId> getBannedMembers() {
124 if (this.group == null) {
125 return Set.of();
126 }
127 return group.bannedMembers.stream()
128 .map(m -> ServiceId.parseOrThrow(m.serviceIdBytes))
129 .map(recipientResolver::resolveRecipient)
130 .collect(Collectors.toSet());
131 }
132
133 @Override
134 public Set<RecipientId> getPendingMembers() {
135 if (this.group == null) {
136 return Set.of();
137 }
138 return group.pendingMembers.stream()
139 .map(m -> ServiceId.parseOrThrow(m.serviceIdBytes))
140 .map(recipientResolver::resolveRecipient)
141 .collect(Collectors.toSet());
142 }
143
144 @Override
145 public Set<RecipientId> getRequestingMembers() {
146 if (this.group == null) {
147 return Set.of();
148 }
149 return group.requestingMembers.stream()
150 .map(m -> ServiceId.parseOrThrow(m.aciBytes))
151 .map(recipientResolver::resolveRecipient)
152 .collect(Collectors.toSet());
153 }
154
155 @Override
156 public Set<RecipientId> getAdminMembers() {
157 if (this.group == null) {
158 return Set.of();
159 }
160 return group.members.stream()
161 .filter(m -> m.role == Member.Role.ADMINISTRATOR)
162 .map(m -> new RecipientAddress(ServiceId.ACI.parseOrNull(m.aciBytes),
163 ServiceId.PNI.parseOrNull(m.pniBytes),
164 null))
165 .map(recipientResolver::resolveRecipient)
166 .collect(Collectors.toSet());
167 }
168
169 @Override
170 public boolean isBlocked() {
171 return blocked;
172 }
173
174 @Override
175 public void setBlocked(final boolean blocked) {
176 this.blocked = blocked;
177 }
178
179 @Override
180 public int getMessageExpirationTimer() {
181 return this.group != null && this.group.disappearingMessagesTimer != null
182 ? this.group.disappearingMessagesTimer.duration
183 : 0;
184 }
185
186 @Override
187 public boolean isAnnouncementGroup() {
188 return this.group != null && this.group.isAnnouncementGroup == EnabledState.ENABLED;
189 }
190
191 @Override
192 public GroupPermission getPermissionAddMember() {
193 final var accessControl = getAccessControl();
194 return accessControl == null ? GroupPermission.EVERY_MEMBER : toGroupPermission(accessControl.members);
195 }
196
197 @Override
198 public GroupPermission getPermissionEditDetails() {
199 final var accessControl = getAccessControl();
200 return accessControl == null ? GroupPermission.EVERY_MEMBER : toGroupPermission(accessControl.attributes);
201 }
202
203 @Override
204 public GroupPermission getPermissionSendMessage() {
205 return isAnnouncementGroup() ? GroupPermission.ONLY_ADMINS : GroupPermission.EVERY_MEMBER;
206 }
207
208 public void setPermissionDenied(final boolean permissionDenied) {
209 this.permissionDenied = permissionDenied;
210 }
211
212 public boolean isPermissionDenied() {
213 return permissionDenied;
214 }
215
216 private AccessControl getAccessControl() {
217 if (this.group == null || this.group.accessControl == null) {
218 return null;
219 }
220
221 return this.group.accessControl;
222 }
223
224 private static GroupPermission toGroupPermission(final AccessControl.AccessRequired permission) {
225 return switch (permission) {
226 case ADMINISTRATOR -> GroupPermission.ONLY_ADMINS;
227 default -> GroupPermission.EVERY_MEMBER;
228 };
229 }
230 }