package org.mercury_im.messenger.core.viewmodel.openpgp; import org.bouncycastle.openpgp.PGPException; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smackx.ox.OpenPgpManager; import org.jivesoftware.smackx.ox.OpenPgpSecretKeyBackupPassphrase; import org.jivesoftware.smackx.ox.exception.InvalidBackupCodeException; import org.jivesoftware.smackx.ox.exception.MissingUserIdOnKeyException; import org.jivesoftware.smackx.ox.exception.NoBackupFoundException; import org.jivesoftware.smackx.pubsub.PubSubException; import org.mercury_im.messenger.core.util.Optional; import org.mercury_im.messenger.core.viewmodel.MercuryViewModel; import org.pgpainless.key.OpenPgpV4Fingerprint; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import javax.inject.Inject; import io.reactivex.Observable; import io.reactivex.subjects.BehaviorSubject; public class OxSecretKeyBackupRestoreViewModel implements MercuryViewModel { private static final Logger LOGGER = Logger.getLogger(OxSecretKeyBackupRestoreViewModel.class.getName()); private final OpenPgpManager openPgpManager; private BehaviorSubject> backupRestoreError = BehaviorSubject.createDefault(new Optional<>()); private BehaviorSubject finished = BehaviorSubject.createDefault(false); //@Inject public OxSecretKeyBackupRestoreViewModel(OpenPgpManager openPgpManager) { this.openPgpManager = openPgpManager; } public Observable> observeBackupRestoreError() { return backupRestoreError; } public void onRestoreCodeEntered(String code) { try { OpenPgpSecretKeyBackupPassphrase passphrase = new OpenPgpSecretKeyBackupPassphrase(code); OpenPgpV4Fingerprint fingerprint = openPgpManager.restoreSecretKeyServerBackup(() -> passphrase); LOGGER.log(Level.INFO, "Successfully restored OX secret key " + fingerprint + " for " + openPgpManager.getOpenPgpSelf().getJid()); finished.onNext(true); } catch (InvalidBackupCodeException e) { LOGGER.log(Level.FINE, "Invalid backup code entered."); backupRestoreError.onNext(new Optional<>(OxBackupRestoreError.invalid_backup_code)); } catch (MissingUserIdOnKeyException e) { LOGGER.log(Level.WARNING, "Invalid or missing user ID on key.", e); backupRestoreError.onNext(new Optional<>(OxBackupRestoreError.invalid_user_id_on_key)); } catch (NoBackupFoundException e) { LOGGER.log(Level.FINE, "No secret key backup found.", e); backupRestoreError.onNext(new Optional<>(OxBackupRestoreError.no_backup_found)); } catch (PGPException e) { LOGGER.log(Level.WARNING, "PGP error while restoring key from server backup.", e); backupRestoreError.onNext(new Optional<>(OxBackupRestoreError.pgp_error)); } catch (InterruptedException | IOException e) { LOGGER.log(Level.SEVERE, "Error occurred while restoring key.", e); backupRestoreError.onNext(new Optional<>(OxBackupRestoreError.other_error)); } catch (PubSubException.NotALeafNodeException | XMPPException.XMPPErrorException | SmackException.NoResponseException e) { LOGGER.log(Level.WARNING, "Network related error encountered while restoring OX secret key.", e); backupRestoreError.onNext(new Optional<>(OxBackupRestoreError.protocol_error)); } catch (SmackException.NotConnectedException | SmackException.NotLoggedInException e) { LOGGER.log(Level.FINE, "Cannot restore OX secret key while not logged in.", e); backupRestoreError.onNext(new Optional<>(OxBackupRestoreError.not_authenticated_error)); } } }