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