]> nmode's Git Repositories - signal-cli/blobdiff - lib/src/main/java/org/asamk/signal/manager/api/RecipientIdentifier.java
Add support for using PNI as recipient
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / api / RecipientIdentifier.java
index 4a66cbb37173ce2e9dce1db900ff75a6bc9267c3..53da2aade3e712fc3833fbcf9737e03376d379c5 100644 (file)
 package org.asamk.signal.manager.api;
 
-import org.asamk.signal.manager.groups.GroupId;
-import org.whispersystems.signalservice.api.push.SignalServiceAddress;
-import org.whispersystems.signalservice.api.util.InvalidNumberException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.whispersystems.signalservice.api.util.PhoneNumberFormatter;
 import org.whispersystems.signalservice.api.util.UuidUtil;
 
 import java.util.UUID;
 
-public abstract class RecipientIdentifier {
+public sealed interface RecipientIdentifier {
 
-    public static class NoteToSelf extends RecipientIdentifier {
+    String getIdentifier();
 
-        @Override
-        public boolean equals(final Object obj) {
-            return obj instanceof NoteToSelf;
-        }
+    record NoteToSelf() implements RecipientIdentifier {
+
+        public static final NoteToSelf INSTANCE = new NoteToSelf();
 
         @Override
-        public int hashCode() {
-            return 5;
+        public String getIdentifier() {
+            return "Note-To-Self";
         }
     }
 
-    public abstract static class Single extends RecipientIdentifier {
-
-        public static Single fromString(String identifier, String localNumber) throws InvalidNumberException {
-            return UuidUtil.isUuid(identifier)
-                    ? new Uuid(UUID.fromString(identifier))
-                    : new Number(PhoneNumberFormatter.formatNumber(identifier, localNumber));
+    sealed interface Single extends RecipientIdentifier {
+
+        static Single fromString(String identifier, String localNumber) throws InvalidNumberException {
+            try {
+                if (UuidUtil.isUuid(identifier)) {
+                    return new Uuid(UUID.fromString(identifier));
+                }
+
+                if (identifier.startsWith("PNI:")) {
+                    final var pni = identifier.substring(4);
+                    if (!UuidUtil.isUuid(pni)) {
+                        throw new InvalidNumberException("Invalid PNI");
+                    }
+                    return new Pni(UUID.fromString(pni));
+                }
+
+                if (identifier.startsWith("u:")) {
+                    return new Username(identifier.substring(2));
+                }
+
+                final var normalizedNumber = PhoneNumberFormatter.formatNumber(identifier, localNumber);
+                if (!normalizedNumber.equals(identifier)) {
+                    final Logger logger = LoggerFactory.getLogger(RecipientIdentifier.class);
+                    logger.debug("Normalized number {} to {}.", identifier, normalizedNumber);
+                }
+                return new Number(normalizedNumber);
+            } catch (org.whispersystems.signalservice.api.util.InvalidNumberException e) {
+                throw new InvalidNumberException(e.getMessage(), e);
+            }
         }
 
-        public static Single fromAddress(SignalServiceAddress address) {
-            return new Uuid(address.getUuid());
+        static Single fromAddress(RecipientAddress address) {
+            if (address.number().isPresent()) {
+                return new Number(address.number().get());
+            } else if (address.aci().isPresent()) {
+                return new Uuid(UUID.fromString(address.aci().get()));
+            } else if (address.pni().isPresent()) {
+                return new Pni(UUID.fromString(address.pni().get().substring(4)));
+            } else if (address.username().isPresent()) {
+                return new Username(address.username().get());
+            }
+            throw new AssertionError("RecipientAddress without identifier");
         }
-    }
-
-    public static class Uuid extends Single {
 
-        public final UUID uuid;
+        RecipientAddress toPartialRecipientAddress();
+    }
 
-        public Uuid(final UUID uuid) {
-            this.uuid = uuid;
-        }
+    record Uuid(UUID uuid) implements Single {
 
         @Override
-        public boolean equals(final Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-
-            final Uuid uuid1 = (Uuid) o;
-
-            return uuid.equals(uuid1.uuid);
+        public String getIdentifier() {
+            return uuid.toString();
         }
 
         @Override
-        public int hashCode() {
-            return uuid.hashCode();
+        public RecipientAddress toPartialRecipientAddress() {
+            return new RecipientAddress(uuid);
         }
     }
 
-    public static class Number extends Single {
-
-        public final String number;
+    record Pni(UUID pni) implements Single {
 
-        public Number(final String number) {
-            this.number = number;
+        @Override
+        public String getIdentifier() {
+            return "PNI:" + pni.toString();
         }
 
         @Override
-        public boolean equals(final Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
+        public RecipientAddress toPartialRecipientAddress() {
+            return new RecipientAddress(null, getIdentifier(), null, null);
+        }
+    }
 
-            final Number number1 = (Number) o;
+    record Number(String number) implements Single {
 
-            return number.equals(number1.number);
+        @Override
+        public String getIdentifier() {
+            return number;
         }
 
         @Override
-        public int hashCode() {
-            return number.hashCode();
+        public RecipientAddress toPartialRecipientAddress() {
+            return new RecipientAddress(number);
         }
     }
 
-    public static class Group extends RecipientIdentifier {
-
-        public final GroupId groupId;
+    record Username(String username) implements Single {
 
-        public Group(final GroupId groupId) {
-            this.groupId = groupId;
+        @Override
+        public String getIdentifier() {
+            return "u:" + username;
         }
 
         @Override
-        public boolean equals(final Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-
-            final Group group = (Group) o;
-
-            return groupId.equals(group.groupId);
+        public RecipientAddress toPartialRecipientAddress() {
+            return new RecipientAddress(null, null, null, username);
         }
+    }
+
+    record Group(GroupId groupId) implements RecipientIdentifier {
 
         @Override
-        public int hashCode() {
-            return groupId.hashCode();
+        public String getIdentifier() {
+            return groupId.toBase64();
         }
     }
 }