diff --git a/app/src/main/java/org/tasks/etesync/AddEteSyncAccountViewModel.java b/app/src/main/java/org/tasks/etesync/AddEteSyncAccountViewModel.java index ba3390874..c19986cb8 100644 --- a/app/src/main/java/org/tasks/etesync/AddEteSyncAccountViewModel.java +++ b/app/src/main/java/org/tasks/etesync/AddEteSyncAccountViewModel.java @@ -17,8 +17,10 @@ public class AddEteSyncAccountViewModel extends CompletableViewModel { + client.setForeground(); playServices.updateSecurityProvider(context); - return client.setForeground().forUrl(url, username, null, null).getInfoAndToken(password); + String token = client.forUrl(url, username, null, null).getToken(password); + return Pair.create(client.forUrl(url, username, null, token).getUserInfo(), token); }); } } diff --git a/app/src/main/java/org/tasks/etesync/EteSyncClient.java b/app/src/main/java/org/tasks/etesync/EteSyncClient.java index 54f4dd38a..ffbf3bcb5 100644 --- a/app/src/main/java/org/tasks/etesync/EteSyncClient.java +++ b/app/src/main/java/org/tasks/etesync/EteSyncClient.java @@ -9,6 +9,7 @@ import androidx.core.util.Pair; import at.bitfire.cert4android.CustomCertManager; import at.bitfire.cert4android.CustomCertManager.CustomHostnameVerifier; import com.etesync.journalmanager.Constants; +import com.etesync.journalmanager.Crypto; import com.etesync.journalmanager.Crypto.CryptoManager; import com.etesync.journalmanager.Exceptions; import com.etesync.journalmanager.Exceptions.HttpException; @@ -152,25 +153,8 @@ public class EteSyncClient { foreground); } - private EteSyncClient withToken(String token) - throws KeyManagementException, NoSuchAlgorithmException { - return new EteSyncClient( - context, - encryption, - preferences, - interceptor, - httpUrl.toString(), - username, - encryptionPassword, - token, - foreground); - } - - Pair getInfoAndToken(String password) - throws IOException, HttpException, NoSuchAlgorithmException, KeyManagementException { - JournalAuthenticator journalAuthenticator = new JournalAuthenticator(httpClient, httpUrl); - String token = journalAuthenticator.getAuthToken(username, password); - return Pair.create(withToken(token).getUserInfo(), token); + String getToken(String password) throws IOException, HttpException { + return new JournalAuthenticator(httpClient, httpUrl).getAuthToken(username, password); } UserInfo getUserInfo() throws HttpException { @@ -178,13 +162,23 @@ public class EteSyncClient { return userInfoManager.fetch(username); } - CryptoManager getCrypto(Journal journal) throws VersionTooNewException, IntegrityException { - return new CryptoManager(journal.getVersion(), encryptionPassword, journal.getUid()); + CryptoManager getCrypto(UserInfo userInfo, Journal journal) + throws VersionTooNewException, IntegrityException { + if (journal.getKey() == null) { + return new CryptoManager(journal.getVersion(), encryptionPassword, journal.getUid()); + } + if (userInfo == null) { + throw new RuntimeException("Missing userInfo"); + } + CryptoManager cryptoManager = new CryptoManager(userInfo.getVersion(), encryptionPassword, "userInfo"); + Crypto.AsymmetricKeyPair keyPair = + new Crypto.AsymmetricKeyPair(userInfo.getContent(cryptoManager), userInfo.getPubkey()); + return new CryptoManager(journal.getVersion(), keyPair, journal.getKey()); } - private @Nullable CollectionInfo convertJournalToCollection(Journal journal) { + private @Nullable CollectionInfo convertJournalToCollection(UserInfo userInfo, Journal journal) { try { - CryptoManager cryptoManager = getCrypto(journal); + CryptoManager cryptoManager = getCrypto(userInfo, journal); journal.verify(cryptoManager); CollectionInfo collection = CollectionInfo.Companion.fromJson(journal.getContent(cryptoManager)); @@ -196,10 +190,11 @@ public class EteSyncClient { } } - public Map getCalendars() throws Exceptions.HttpException { + public Map getCalendars(UserInfo userInfo) + throws Exceptions.HttpException { Map result = new HashMap<>(); for (Journal journal : journalManager.list()) { - CollectionInfo collection = convertJournalToCollection(journal); + CollectionInfo collection = convertJournalToCollection(userInfo, journal); if (collection != null) { if (TYPE_TASKS.equals(collection.getType())) { Timber.v("Found %s", collection); @@ -213,11 +208,14 @@ public class EteSyncClient { } void getSyncEntries( - Journal journal, CaldavCalendar calendar, Callback>> callback) + UserInfo userInfo, + Journal journal, + CaldavCalendar calendar, + Callback>> callback) throws IntegrityException, Exceptions.HttpException, VersionTooNewException { JournalEntryManager journalEntryManager = new JournalEntryManager(httpClient, httpUrl, journal.getUid()); - CryptoManager crypto = getCrypto(journal); + CryptoManager crypto = getCrypto(userInfo, journal); List journalEntries; do { journalEntries = journalEntryManager.list(crypto, calendar.getCtag(), MAX_FETCH); @@ -235,9 +233,8 @@ public class EteSyncClient { } } - EteSyncClient setForeground() { + void setForeground() { foreground = true; - return this; } void invalidateToken() { @@ -266,10 +263,11 @@ public class EteSyncClient { throws VersionTooNewException, IntegrityException, HttpException { String uid = calendar.getUrl(); Journal journal = journalManager.fetch(uid); - CollectionInfo collectionInfo = convertJournalToCollection(journal); + UserInfo userInfo = getUserInfo(); + CryptoManager crypto = getCrypto(userInfo, journal); + CollectionInfo collectionInfo = convertJournalToCollection(userInfo, journal); collectionInfo.setDisplayName(name); collectionInfo.setColor(color == 0 ? null : color); - CryptoManager crypto = new CryptoManager(collectionInfo.getVersion(), encryptionPassword, uid); journalManager.update(new Journal(crypto, collectionInfo.toJson(), uid)); return uid; } diff --git a/app/src/main/java/org/tasks/etesync/EteSynchronizer.java b/app/src/main/java/org/tasks/etesync/EteSynchronizer.java index 357eeb001..484135f18 100644 --- a/app/src/main/java/org/tasks/etesync/EteSynchronizer.java +++ b/app/src/main/java/org/tasks/etesync/EteSynchronizer.java @@ -20,6 +20,7 @@ import com.etesync.journalmanager.Exceptions.VersionTooNewException; import com.etesync.journalmanager.JournalEntryManager; import com.etesync.journalmanager.JournalEntryManager.Entry; import com.etesync.journalmanager.JournalManager.Journal; +import com.etesync.journalmanager.UserInfoManager.UserInfo; import com.etesync.journalmanager.model.CollectionInfo; import com.etesync.journalmanager.model.SyncEntry; import com.etesync.journalmanager.model.SyncEntry.Actions; @@ -129,7 +130,8 @@ public class EteSynchronizer { throws KeyManagementException, NoSuchAlgorithmException, Exceptions.HttpException, IntegrityException, VersionTooNewException { EteSyncClient client = this.client.forAccount(account); - Map resources = client.getCalendars(); + UserInfo userInfo = client.getUserInfo(); + Map resources = client.getCalendars(userInfo); Set uids = newHashSet(Iterables.transform(resources.values(), CollectionInfo::getUid)); Timber.d("Found uids: %s", uids); @@ -162,7 +164,7 @@ public class EteSynchronizer { localBroadcastManager.broadcastRefreshList(); } } - sync(client, calendar, entry.getKey()); + sync(client, userInfo, calendar, entry.getKey()); } setError(account, ""); } @@ -176,7 +178,8 @@ public class EteSynchronizer { } } - private void sync(EteSyncClient client, CaldavCalendar caldavCalendar, Journal journal) + private void sync( + EteSyncClient client, UserInfo userInfo, CaldavCalendar caldavCalendar, Journal journal) throws IntegrityException, Exceptions.HttpException, VersionTooNewException { Timber.d("sync(%s)", caldavCalendar); @@ -189,6 +192,7 @@ public class EteSynchronizer { if (Strings.isNullOrEmpty(remoteCtag) || !remoteCtag.equals(caldavCalendar.getCtag())) { Timber.v("Applying remote changes"); client.getSyncEntries( + userInfo, journal, caldavCalendar, syncEntries -> applyEntries(caldavCalendar, syncEntries, localChanges.keySet())); @@ -218,7 +222,7 @@ public class EteSynchronizer { } remoteCtag = caldavCalendar.getCtag(); - CryptoManager crypto = client.getCrypto(journal); + CryptoManager crypto = client.getCrypto(userInfo, journal); List> updates = new ArrayList<>(); JournalEntryManager.Entry previous = Strings.isNullOrEmpty(remoteCtag) ? null : Entry.getFakeWithUid(remoteCtag); diff --git a/app/src/main/java/org/tasks/etesync/UpdateEteSyncAccountViewModel.java b/app/src/main/java/org/tasks/etesync/UpdateEteSyncAccountViewModel.java index ef0fb6168..3d25864d9 100644 --- a/app/src/main/java/org/tasks/etesync/UpdateEteSyncAccountViewModel.java +++ b/app/src/main/java/org/tasks/etesync/UpdateEteSyncAccountViewModel.java @@ -16,10 +16,14 @@ public class UpdateEteSyncAccountViewModel extends CompletableViewModel { - EteSyncClient newClient = client.setForeground().forUrl(url, username, null, token); - return Strings.isNullOrEmpty(password) - ? Pair.create(newClient.getUserInfo(), token) - : newClient.getInfoAndToken(password); + client.setForeground(); + if (Strings.isNullOrEmpty(password)) { + return Pair.create(client.forUrl(url, username, null, token).getUserInfo(), token); + } else { + String newToken = client.forUrl(url, username, null, null).getToken(password); + return Pair.create( + client.forUrl(url, username, null, newToken).getUserInfo(), newToken); + } }); } }