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