diff --git a/app/src/main/java/org/mercury_im/messenger/android/ui/account/detail/AccountDetailsFragment.java b/app/src/main/java/org/mercury_im/messenger/android/ui/account/detail/AccountDetailsFragment.java index 2880f19..d4bd202 100644 --- a/app/src/main/java/org/mercury_im/messenger/android/ui/account/detail/AccountDetailsFragment.java +++ b/app/src/main/java/org/mercury_im/messenger/android/ui/account/detail/AccountDetailsFragment.java @@ -137,6 +137,9 @@ public class AccountDetailsFragment extends Fragment { .replace(R.id.fragment, IkeySetupFragment.newInstance(accountId)) .commit(); return true; + case R.id.action_publish_ikey_element: + sendIkeyElement(); + return true; } return super.onOptionsItemSelected(item); } diff --git a/app/src/main/java/org/mercury_im/messenger/android/ui/contacts/detail/AndroidContactDetailViewModel.java b/app/src/main/java/org/mercury_im/messenger/android/ui/contacts/detail/AndroidContactDetailViewModel.java index c8c860f..dc9beb4 100644 --- a/app/src/main/java/org/mercury_im/messenger/android/ui/contacts/detail/AndroidContactDetailViewModel.java +++ b/app/src/main/java/org/mercury_im/messenger/android/ui/contacts/detail/AndroidContactDetailViewModel.java @@ -9,38 +9,15 @@ import androidx.lifecycle.ViewModel; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.Presence; -import org.jivesoftware.smack.roster.PresenceEventListener; -import org.jivesoftware.smack.roster.Roster; -import org.jivesoftware.smack.roster.RosterEntry; -import org.jivesoftware.smack.roster.RosterGroup; -import org.jivesoftware.smackx.ikey.util.IkeyTrust; -import org.jivesoftware.smackx.ox.store.definition.OpenPgpTrustStore; -import org.jxmpp.jid.BareJid; -import org.jxmpp.jid.EntityBareJid; -import org.jxmpp.jid.Jid; -import org.jxmpp.jid.impl.JidCreate; import org.mercury_im.messenger.android.MercuryImApplication; +import org.mercury_im.messenger.android.ui.avatar.AvatarDrawable; import org.mercury_im.messenger.android.ui.base.MercuryAndroidViewModel; -import org.mercury_im.messenger.core.Messenger; -import org.mercury_im.messenger.core.SchedulersFacade; -import org.mercury_im.messenger.core.crypto.ikey.IkeyRepository; -import org.mercury_im.messenger.core.data.repository.DirectChatRepository; -import org.mercury_im.messenger.core.data.repository.OpenPgpRepository; -import org.mercury_im.messenger.core.data.repository.PeerRepository; import org.mercury_im.messenger.core.util.Optional; -import org.mercury_im.messenger.core.util.Tuple; -import org.mercury_im.messenger.core.viewmodel.MercuryViewModel; import org.mercury_im.messenger.core.viewmodel.contact.ContactDetailViewModel; import org.mercury_im.messenger.core.viewmodel.openpgp.FingerprintViewItem; -import org.mercury_im.messenger.entity.chat.Chat; -import org.mercury_im.messenger.android.ui.avatar.AvatarDrawable; -import org.mercury_im.messenger.core.util.CombinedPresenceListener; -import org.mercury_im.messenger.entity.contact.Peer; import org.pgpainless.key.OpenPgpV4Fingerprint; -import java.util.ArrayList; import java.util.Collections; -import java.util.Date; import java.util.List; import java.util.Objects; import java.util.UUID; @@ -49,8 +26,6 @@ import javax.inject.Inject; import io.reactivex.Completable; import io.reactivex.Single; -import io.reactivex.disposables.CompositeDisposable; -import io.reactivex.functions.BiFunction; public class AndroidContactDetailViewModel extends ViewModel implements MercuryAndroidViewModel { @@ -99,12 +74,6 @@ public class AndroidContactDetailViewModel extends ViewModel implements MercuryA return contactAddress; } - @Override - protected void onCleared() { - super.onCleared(); - commonViewModel.dispose(); - } - public LiveData getAccountId() { return contactAccountId; } diff --git a/app/src/main/java/org/mercury_im/messenger/android/ui/contacts/detail/ContactDetailActivity.java b/app/src/main/java/org/mercury_im/messenger/android/ui/contacts/detail/ContactDetailActivity.java index 681aea8..5ab2de6 100644 --- a/app/src/main/java/org/mercury_im/messenger/android/ui/contacts/detail/ContactDetailActivity.java +++ b/app/src/main/java/org/mercury_im/messenger/android/ui/contacts/detail/ContactDetailActivity.java @@ -20,6 +20,7 @@ import javax.inject.Inject; import butterknife.ButterKnife; import io.reactivex.Completable; import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; import io.reactivex.schedulers.Schedulers; import lombok.Value; @@ -29,6 +30,8 @@ public class ContactDetailActivity extends AppCompatActivity implements MercuryA private AndroidContactDetailViewModel androidContactDetailViewModel; private UUID peerId; + Disposable disposable; + @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -40,7 +43,7 @@ public class ContactDetailActivity extends AppCompatActivity implements MercuryA androidContactDetailViewModel = new ViewModelProvider(this).get(AndroidContactDetailViewModel.class); bindUiComponents(); - androidContactDetailViewModel.init(peerId) + disposable = androidContactDetailViewModel.init(peerId) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(); @@ -65,4 +68,10 @@ public class ContactDetailActivity extends AppCompatActivity implements MercuryA private class Arguments { UUID peerId; } + + @Override + protected void onDestroy() { + super.onDestroy(); + disposable.dispose(); + } } diff --git a/app/src/main/res/menu/menu_account_details.xml b/app/src/main/res/menu/menu_account_details.xml index ee9bd3b..a00876b 100644 --- a/app/src/main/res/menu/menu_account_details.xml +++ b/app/src/main/res/menu/menu_account_details.xml @@ -27,4 +27,8 @@ android:id="@+id/action_setup_ikey" android:title="Ikey Setup" /> + + \ No newline at end of file diff --git a/domain/src/main/java/org/jivesoftware/smackx/ikey/IkeyManager.java b/domain/src/main/java/org/jivesoftware/smackx/ikey/IkeyManager.java index 9ae7c0f..1df51d1 100644 --- a/domain/src/main/java/org/jivesoftware/smackx/ikey/IkeyManager.java +++ b/domain/src/main/java/org/jivesoftware/smackx/ikey/IkeyManager.java @@ -163,11 +163,19 @@ public final class IkeyManager extends Manager { return new IkeyElement(mechanism.getType(), superordinateElement, signedElement, proofElement); } - public void publishIkeyElement(IkeyElement ikeyElement) + public void storeAndPublishElement(IkeyElement ikeyElement) throws InterruptedException, PubSubException.NotALeafNodeException, XMPPException.XMPPErrorException, - SmackException.NotConnectedException, SmackException.NoResponseException { + SmackException.NotConnectedException, SmackException.NoResponseException, IOException, PGPException { + store.storeIkeyRecord(connection().getUser().asEntityBareJid(), elementToRecord(ikeyElement)); + publishIkeyElement(ikeyElement); + } + + public void publishIkeyElement(IkeyElement element) + throws InterruptedException, PubSubException.NotALeafNodeException, + XMPPException.XMPPErrorException, SmackException.NotConnectedException, + SmackException.NoResponseException { PepManager.getInstanceFor(connection()) - .publish(IkeyConstants.SUBORDINATES_NODE, new PayloadItem<>(ikeyElement)); + .publish(IkeyConstants.SUBORDINATES_NODE, new PayloadItem<>(element)); } public IkeyElement fetchIkeyElementOf(EntityBareJid jid) @@ -201,7 +209,8 @@ public final class IkeyManager extends Manager { throws IOException, UnsupportedSignatureAlgorithmException, PGPException { IkeyRecord newRecord = elementToRecord(element); if (isFromTheFuture(newRecord)) { - LOGGER.log(Level.WARNING, "Received ikey element appears to be from the future: " + element.getSignedElement().getChildElement().getTimestamp()); + LOGGER.log(Level.WARNING, "Received ikey element appears to be from the future: " + + newRecord.getTimestamp()); return; } @@ -307,9 +316,9 @@ public final class IkeyManager extends Manager { } private static boolean isFromTheFuture(IkeyRecord record) { - Date elementTimestamp = record.getTimestamp(); + Date timestamp = record.getTimestamp(); Date now = new Date(); - return elementTimestamp.after(now); + return timestamp.after(now); } private boolean existsSameOrNewerRecord(IkeyRecord record) throws IOException { diff --git a/domain/src/main/java/org/mercury_im/messenger/core/viewmodel/account/detail/AccountDetailsViewModel.java b/domain/src/main/java/org/mercury_im/messenger/core/viewmodel/account/detail/AccountDetailsViewModel.java index d8f1ece..ba422b6 100644 --- a/domain/src/main/java/org/mercury_im/messenger/core/viewmodel/account/detail/AccountDetailsViewModel.java +++ b/domain/src/main/java/org/mercury_im/messenger/core/viewmodel/account/detail/AccountDetailsViewModel.java @@ -1,6 +1,5 @@ package org.mercury_im.messenger.core.viewmodel.account.detail; -import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smackx.ikey.IkeyManager; @@ -88,7 +87,7 @@ public class AccountDetailsViewModel implements MercuryViewModel { IkeyElement ikeyElement = syncCreateIkeyElement(accountId); IkeyManager ikeyManager = IkeyManager.getInstanceFor(connectionManager.getConnection(accountId).getConnection()); - ikeyManager.publishIkeyElement(ikeyElement); + ikeyManager.storeAndPublishElement(ikeyElement); }) .compose(schedulers.executeUiSafeCompletable()) .subscribe( @@ -96,7 +95,7 @@ public class AccountDetailsViewModel implements MercuryViewModel { e -> LOGGER.log(Level.SEVERE, "Error publishing ikey element:", e))); } - private IkeyElement syncCreateIkeyElement(UUID accountId) throws URISyntaxException, PGPException, IOException { + private IkeyElement syncCreateIkeyElement(UUID accountId) throws URISyntaxException, IOException { MercuryConnection connection = connectionManager.getConnection(accountId); IkeyManager ikeyManager = ikeyInitializer.initFor(connection); @@ -124,8 +123,9 @@ public class AccountDetailsViewModel implements MercuryViewModel { subordinateElements.add(new SubordinateElement("urn:xmpp:openpgp:0", u, fp.toString())); } - PGPSecretKeyRing secretKeys = openPgpRepository.loadSecretKeysOf(accountId, account.getJid()) - .blockingGet().getSecretKeyRing(localFp.getKeyId()); + PGPSecretKeyRing secretKeys = ikeyRepository.loadSecretKey(accountId) + .blockingFirst(new Optional<>()) + .getItem(); IkeyElement ikeyElement = ikeyManager.createOxIkeyElement(secretKeys, new UnprotectedKeysProtector(), subordinateElements.toArray(new SubordinateElement[]{}));