]> nmode's Git Repositories - signal-cli/blobdiff - src/main/java/org/asamk/signal/storage/SignalAccount.java
Move group classes to separate package
[signal-cli] / src / main / java / org / asamk / signal / storage / SignalAccount.java
index dbb0ac0463c2a16f7586cec01358604d811efb70..393d04490e0229f6140004e90a3d64707c7157eb 100644 (file)
@@ -10,6 +10,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.SerializationFeature;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 
+import org.asamk.signal.manager.groups.GroupId;
 import org.asamk.signal.storage.contacts.ContactInfo;
 import org.asamk.signal.storage.contacts.JsonContactsStore;
 import org.asamk.signal.storage.groups.GroupInfo;
@@ -28,6 +29,8 @@ import org.asamk.signal.util.IOUtils;
 import org.asamk.signal.util.Util;
 import org.signal.zkgroup.InvalidInputException;
 import org.signal.zkgroup.profiles.ProfileKey;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.whispersystems.libsignal.IdentityKeyPair;
 import org.whispersystems.libsignal.state.PreKeyRecord;
 import org.whispersystems.libsignal.state.SignedPreKeyRecord;
@@ -52,6 +55,8 @@ import java.util.stream.Collectors;
 
 public class SignalAccount implements Closeable {
 
+    final static Logger logger = LoggerFactory.getLogger(SignalAccount.class);
+
     private final ObjectMapper jsonProcessor = new ObjectMapper();
     private final FileChannel fileChannel;
     private final FileLock lock;
@@ -85,8 +90,8 @@ public class SignalAccount implements Closeable {
         jsonProcessor.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET);
     }
 
-    public static SignalAccount load(String dataPath, String username) throws IOException {
-        final String fileName = getFileName(dataPath, username);
+    public static SignalAccount load(File dataPath, String username) throws IOException {
+        final File fileName = getFileName(dataPath, username);
         final Pair<FileChannel, FileLock> pair = openFileChannel(fileName);
         try {
             SignalAccount account = new SignalAccount(pair.first(), pair.second());
@@ -99,10 +104,12 @@ public class SignalAccount implements Closeable {
         }
     }
 
-    public static SignalAccount create(String dataPath, String username, IdentityKeyPair identityKey, int registrationId, ProfileKey profileKey) throws IOException {
+    public static SignalAccount create(
+            File dataPath, String username, IdentityKeyPair identityKey, int registrationId, ProfileKey profileKey
+    ) throws IOException {
         IOUtils.createPrivateDirectories(dataPath);
-        String fileName = getFileName(dataPath, username);
-        if (!new File(fileName).exists()) {
+        File fileName = getFileName(dataPath, username);
+        if (!fileName.exists()) {
             IOUtils.createPrivateFile(fileName);
         }
 
@@ -122,10 +129,20 @@ public class SignalAccount implements Closeable {
         return account;
     }
 
-    public static SignalAccount createLinkedAccount(String dataPath, String username, UUID uuid, String password, int deviceId, IdentityKeyPair identityKey, int registrationId, String signalingKey, ProfileKey profileKey) throws IOException {
+    public static SignalAccount createLinkedAccount(
+            File dataPath,
+            String username,
+            UUID uuid,
+            String password,
+            int deviceId,
+            IdentityKeyPair identityKey,
+            int registrationId,
+            String signalingKey,
+            ProfileKey profileKey
+    ) throws IOException {
         IOUtils.createPrivateDirectories(dataPath);
-        String fileName = getFileName(dataPath, username);
-        if (!new File(fileName).exists()) {
+        File fileName = getFileName(dataPath, username);
+        if (!fileName.exists()) {
             IOUtils.createPrivateFile(fileName);
         }
 
@@ -150,23 +167,31 @@ public class SignalAccount implements Closeable {
         return account;
     }
 
-    public static String getFileName(String dataPath, String username) {
-        return dataPath + "/" + username;
+    public static File getFileName(File dataPath, String username) {
+        return new File(dataPath, username);
+    }
+
+    private static File getUserPath(final File dataPath, final String username) {
+        return new File(dataPath, username + ".d");
+    }
+
+    public static File getMessageCachePath(File dataPath, String username) {
+        return new File(getUserPath(dataPath, username), "msg-cache");
     }
 
-    private static File getGroupCachePath(String dataPath, String username) {
-        return new File(new File(dataPath, username + ".d"), "group-cache");
+    private static File getGroupCachePath(File dataPath, String username) {
+        return new File(getUserPath(dataPath, username), "group-cache");
     }
 
-    public static boolean userExists(String dataPath, String username) {
+    public static boolean userExists(File dataPath, String username) {
         if (username == null) {
             return false;
         }
-        File f = new File(getFileName(dataPath, username));
+        File f = getFileName(dataPath, username);
         return !(!f.exists() || f.isDirectory());
     }
 
-    private void load(String dataPath) throws IOException {
+    private void load(File dataPath) throws IOException {
         JsonNode rootNode;
         synchronized (fileChannel) {
             fileChannel.position(0);
@@ -209,11 +234,14 @@ public class SignalAccount implements Closeable {
             try {
                 profileKey = new ProfileKey(Base64.decode(Util.getNotNullNode(rootNode, "profileKey").asText()));
             } catch (InvalidInputException e) {
-                throw new IOException("Config file contains an invalid profileKey, needs to be base64 encoded array of 32 bytes", e);
+                throw new IOException(
+                        "Config file contains an invalid profileKey, needs to be base64 encoded array of 32 bytes",
+                        e);
             }
         }
 
-        signalProtocolStore = jsonProcessor.convertValue(Util.getNotNullNode(rootNode, "axolotlStore"), JsonSignalProtocolStore.class);
+        signalProtocolStore = jsonProcessor.convertValue(Util.getNotNullNode(rootNode, "axolotlStore"),
+                JsonSignalProtocolStore.class);
         registered = Util.getNotNullNode(rootNode, "registered").asBoolean();
         JsonNode groupStoreNode = rootNode.get("groupStore");
         if (groupStoreNode != null) {
@@ -281,7 +309,8 @@ public class SignalAccount implements Closeable {
 
         JsonNode threadStoreNode = rootNode.get("threadStore");
         if (threadStoreNode != null) {
-            LegacyJsonThreadStore threadStore = jsonProcessor.convertValue(threadStoreNode, LegacyJsonThreadStore.class);
+            LegacyJsonThreadStore threadStore = jsonProcessor.convertValue(threadStoreNode,
+                    LegacyJsonThreadStore.class);
             // Migrate thread info to group and contact store
             for (ThreadInfo thread : threadStore.getThreads()) {
                 if (thread.id == null || thread.id.isEmpty()) {
@@ -293,7 +322,7 @@ public class SignalAccount implements Closeable {
                         contactInfo.messageExpirationTime = thread.messageExpirationTime;
                         contactStore.updateContact(contactInfo);
                     } else {
-                        GroupInfo groupInfo = groupStore.getGroup(Base64.decode(thread.id));
+                        GroupInfo groupInfo = groupStore.getGroup(GroupId.fromBase64(thread.id));
                         if (groupInfo instanceof GroupInfoV1) {
                             ((GroupInfoV1) groupInfo).messageExpirationTime = thread.messageExpirationTime;
                             groupStore.updateGroup(groupInfo);
@@ -326,8 +355,7 @@ public class SignalAccount implements Closeable {
                 .putPOJO("contactStore", contactStore)
                 .putPOJO("recipientStore", recipientStore)
                 .putPOJO("profileStore", profileStore)
-                .putPOJO("stickerStore", stickerStore)
-        ;
+                .putPOJO("stickerStore", stickerStore);
         try {
             try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
                 // Write to memory first to prevent corrupting the file in case of serialization errors
@@ -341,17 +369,17 @@ public class SignalAccount implements Closeable {
                 }
             }
         } catch (Exception e) {
-            System.err.println(String.format("Error saving file: %s", e.getMessage()));
+            logger.error("Error saving file: {}", e.getMessage());
         }
     }
 
-    private static Pair<FileChannel, FileLock> openFileChannel(String fileName) throws IOException {
-        FileChannel fileChannel = new RandomAccessFile(new File(fileName), "rw").getChannel();
+    private static Pair<FileChannel, FileLock> openFileChannel(File fileName) throws IOException {
+        FileChannel fileChannel = new RandomAccessFile(fileName, "rw").getChannel();
         FileLock lock = fileChannel.tryLock();
         if (lock == null) {
-            System.err.println("Config file is in use by another instance, waiting…");
+            logger.info("Config file is in use by another instance, waiting…");
             lock = fileChannel.lock();
-            System.err.println("Config file lock acquired.");
+            logger.info("Config file lock acquired.");
         }
         return new Pair<>(fileChannel, lock);
     }