Support decryption of shared journals

pull/935/head
Alex Baker 4 years ago
parent a31cdb777b
commit 29d1b54ca7

@ -17,8 +17,10 @@ public class AddEteSyncAccountViewModel extends CompletableViewModel<Pair<UserIn
String password) {
run(
() -> {
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);
});
}
}

@ -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<UserInfo, String> 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<Journal, CollectionInfo> getCalendars() throws Exceptions.HttpException {
public Map<Journal, CollectionInfo> getCalendars(UserInfo userInfo)
throws Exceptions.HttpException {
Map<Journal, CollectionInfo> 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<List<Pair<Entry, SyncEntry>>> callback)
UserInfo userInfo,
Journal journal,
CaldavCalendar calendar,
Callback<List<Pair<Entry, SyncEntry>>> callback)
throws IntegrityException, Exceptions.HttpException, VersionTooNewException {
JournalEntryManager journalEntryManager =
new JournalEntryManager(httpClient, httpUrl, journal.getUid());
CryptoManager crypto = getCrypto(journal);
CryptoManager crypto = getCrypto(userInfo, journal);
List<Entry> 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;
}

@ -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<Journal, CollectionInfo> resources = client.getCalendars();
UserInfo userInfo = client.getUserInfo();
Map<Journal, CollectionInfo> resources = client.getCalendars(userInfo);
Set<String> 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<Pair<Entry, SyncEntry>> updates = new ArrayList<>();
JournalEntryManager.Entry previous =
Strings.isNullOrEmpty(remoteCtag) ? null : Entry.getFakeWithUid(remoteCtag);

@ -16,10 +16,14 @@ public class UpdateEteSyncAccountViewModel extends CompletableViewModel<Pair<Use
@Nullable String token) {
run(
() -> {
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);
}
});
}
}

Loading…
Cancel
Save