]> nmode's Git Repositories - signal-cli/blob - src/main/java/org/asamk/signal/manager/groups/GroupInviteLinkUrl.java
Convert gradle scripts to kotlin
[signal-cli] / src / main / java / org / asamk / signal / manager / groups / GroupInviteLinkUrl.java
1 package org.asamk.signal.manager.groups;
2
3 import com.google.protobuf.ByteString;
4
5 import org.signal.storageservice.protos.groups.GroupInviteLink;
6 import org.signal.storageservice.protos.groups.local.DecryptedGroup;
7 import org.signal.zkgroup.InvalidInputException;
8 import org.signal.zkgroup.groups.GroupMasterKey;
9 import org.whispersystems.util.Base64UrlSafe;
10
11 import java.io.IOException;
12 import java.net.URI;
13 import java.net.URISyntaxException;
14
15 public final class GroupInviteLinkUrl {
16
17 private static final String GROUP_URL_HOST = "signal.group";
18 private static final String GROUP_URL_PREFIX = "https://" + GROUP_URL_HOST + "/#";
19
20 private final GroupMasterKey groupMasterKey;
21 private final GroupLinkPassword password;
22 private final String url;
23
24 public static GroupInviteLinkUrl forGroup(GroupMasterKey groupMasterKey, DecryptedGroup group) {
25 return new GroupInviteLinkUrl(groupMasterKey,
26 GroupLinkPassword.fromBytes(group.getInviteLinkPassword().toByteArray()));
27 }
28
29 public static boolean isGroupLink(String urlString) {
30 return getGroupUrl(urlString) != null;
31 }
32
33 /**
34 * @return null iff not a group url.
35 * @throws InvalidGroupLinkException If group url, but cannot be parsed.
36 */
37 public static GroupInviteLinkUrl fromUri(String urlString) throws InvalidGroupLinkException, UnknownGroupLinkVersionException {
38 URI uri = getGroupUrl(urlString);
39
40 if (uri == null) {
41 return null;
42 }
43
44 try {
45 if (!"/".equals(uri.getPath()) && uri.getPath().length() > 0) {
46 throw new InvalidGroupLinkException("No path was expected in uri");
47 }
48
49 String encoding = uri.getFragment();
50
51 if (encoding == null || encoding.length() == 0) {
52 throw new InvalidGroupLinkException("No reference was in the uri");
53 }
54
55 byte[] bytes = Base64UrlSafe.decodePaddingAgnostic(encoding);
56 GroupInviteLink groupInviteLink = GroupInviteLink.parseFrom(bytes);
57
58 switch (groupInviteLink.getContentsCase()) {
59 case V1CONTENTS: {
60 GroupInviteLink.GroupInviteLinkContentsV1 groupInviteLinkContentsV1 = groupInviteLink.getV1Contents();
61 GroupMasterKey groupMasterKey = new GroupMasterKey(groupInviteLinkContentsV1.getGroupMasterKey()
62 .toByteArray());
63 GroupLinkPassword password = GroupLinkPassword.fromBytes(groupInviteLinkContentsV1.getInviteLinkPassword()
64 .toByteArray());
65
66 return new GroupInviteLinkUrl(groupMasterKey, password);
67 }
68 default:
69 throw new UnknownGroupLinkVersionException("Url contains no known group link content");
70 }
71 } catch (InvalidInputException | IOException e) {
72 throw new InvalidGroupLinkException(e);
73 }
74 }
75
76 /**
77 * @return {@link URI} if the host name matches.
78 */
79 private static URI getGroupUrl(String urlString) {
80 try {
81 URI url = new URI(urlString);
82
83 if (!"https".equalsIgnoreCase(url.getScheme()) && !"sgnl".equalsIgnoreCase(url.getScheme())) {
84 return null;
85 }
86
87 return GROUP_URL_HOST.equalsIgnoreCase(url.getHost()) ? url : null;
88 } catch (URISyntaxException e) {
89 return null;
90 }
91 }
92
93 private GroupInviteLinkUrl(GroupMasterKey groupMasterKey, GroupLinkPassword password) {
94 this.groupMasterKey = groupMasterKey;
95 this.password = password;
96 this.url = createUrl(groupMasterKey, password);
97 }
98
99 protected static String createUrl(GroupMasterKey groupMasterKey, GroupLinkPassword password) {
100 GroupInviteLink groupInviteLink = GroupInviteLink.newBuilder()
101 .setV1Contents(GroupInviteLink.GroupInviteLinkContentsV1.newBuilder()
102 .setGroupMasterKey(ByteString.copyFrom(groupMasterKey.serialize()))
103 .setInviteLinkPassword(ByteString.copyFrom(password.serialize())))
104 .build();
105
106 String encoding = Base64UrlSafe.encodeBytesWithoutPadding(groupInviteLink.toByteArray());
107
108 return GROUP_URL_PREFIX + encoding;
109 }
110
111 public String getUrl() {
112 return url;
113 }
114
115 public GroupMasterKey getGroupMasterKey() {
116 return groupMasterKey;
117 }
118
119 public GroupLinkPassword getPassword() {
120 return password;
121 }
122
123 public final static class InvalidGroupLinkException extends Exception {
124
125 public InvalidGroupLinkException(String message) {
126 super(message);
127 }
128
129 public InvalidGroupLinkException(Throwable cause) {
130 super(cause);
131 }
132 }
133
134 public final static class UnknownGroupLinkVersionException extends Exception {
135
136 public UnknownGroupLinkVersionException(String message) {
137 super(message);
138 }
139 }
140 }