mirror of
https://codeberg.org/Mercury-IM/Mercury-IM
synced 2024-06-24 12:34:51 +02:00
Publish correct superordinate key
This commit is contained in:
parent
1e3c98abea
commit
c4e672cc21
|
@ -137,6 +137,9 @@ public class AccountDetailsFragment extends Fragment {
|
||||||
.replace(R.id.fragment, IkeySetupFragment.newInstance(accountId))
|
.replace(R.id.fragment, IkeySetupFragment.newInstance(accountId))
|
||||||
.commit();
|
.commit();
|
||||||
return true;
|
return true;
|
||||||
|
case R.id.action_publish_ikey_element:
|
||||||
|
sendIkeyElement();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,38 +9,15 @@ import androidx.lifecycle.ViewModel;
|
||||||
import org.jivesoftware.smack.SmackException;
|
import org.jivesoftware.smack.SmackException;
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smack.packet.Presence;
|
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.MercuryImApplication;
|
||||||
|
import org.mercury_im.messenger.android.ui.avatar.AvatarDrawable;
|
||||||
import org.mercury_im.messenger.android.ui.base.MercuryAndroidViewModel;
|
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.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.contact.ContactDetailViewModel;
|
||||||
import org.mercury_im.messenger.core.viewmodel.openpgp.FingerprintViewItem;
|
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 org.pgpainless.key.OpenPgpV4Fingerprint;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -49,8 +26,6 @@ import javax.inject.Inject;
|
||||||
|
|
||||||
import io.reactivex.Completable;
|
import io.reactivex.Completable;
|
||||||
import io.reactivex.Single;
|
import io.reactivex.Single;
|
||||||
import io.reactivex.disposables.CompositeDisposable;
|
|
||||||
import io.reactivex.functions.BiFunction;
|
|
||||||
|
|
||||||
public class AndroidContactDetailViewModel extends ViewModel implements MercuryAndroidViewModel<ContactDetailViewModel> {
|
public class AndroidContactDetailViewModel extends ViewModel implements MercuryAndroidViewModel<ContactDetailViewModel> {
|
||||||
|
|
||||||
|
@ -99,12 +74,6 @@ public class AndroidContactDetailViewModel extends ViewModel implements MercuryA
|
||||||
return contactAddress;
|
return contactAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCleared() {
|
|
||||||
super.onCleared();
|
|
||||||
commonViewModel.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
public LiveData<UUID> getAccountId() {
|
public LiveData<UUID> getAccountId() {
|
||||||
return contactAccountId;
|
return contactAccountId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import javax.inject.Inject;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import io.reactivex.Completable;
|
import io.reactivex.Completable;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.disposables.Disposable;
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
|
|
||||||
|
@ -29,6 +30,8 @@ public class ContactDetailActivity extends AppCompatActivity implements MercuryA
|
||||||
private AndroidContactDetailViewModel androidContactDetailViewModel;
|
private AndroidContactDetailViewModel androidContactDetailViewModel;
|
||||||
private UUID peerId;
|
private UUID peerId;
|
||||||
|
|
||||||
|
Disposable disposable;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@ -40,7 +43,7 @@ public class ContactDetailActivity extends AppCompatActivity implements MercuryA
|
||||||
androidContactDetailViewModel = new ViewModelProvider(this).get(AndroidContactDetailViewModel.class);
|
androidContactDetailViewModel = new ViewModelProvider(this).get(AndroidContactDetailViewModel.class);
|
||||||
bindUiComponents();
|
bindUiComponents();
|
||||||
|
|
||||||
androidContactDetailViewModel.init(peerId)
|
disposable = androidContactDetailViewModel.init(peerId)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe();
|
.subscribe();
|
||||||
|
@ -65,4 +68,10 @@ public class ContactDetailActivity extends AppCompatActivity implements MercuryA
|
||||||
private class Arguments {
|
private class Arguments {
|
||||||
UUID peerId;
|
UUID peerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
disposable.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,4 +27,8 @@
|
||||||
android:id="@+id/action_setup_ikey"
|
android:id="@+id/action_setup_ikey"
|
||||||
android:title="Ikey Setup" />
|
android:title="Ikey Setup" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_publish_ikey_element"
|
||||||
|
android:title="Publish Ikey Element" />
|
||||||
|
|
||||||
</menu>
|
</menu>
|
|
@ -163,11 +163,19 @@ public final class IkeyManager extends Manager {
|
||||||
return new IkeyElement(mechanism.getType(), superordinateElement, signedElement, proofElement);
|
return new IkeyElement(mechanism.getType(), superordinateElement, signedElement, proofElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void publishIkeyElement(IkeyElement ikeyElement)
|
public void storeAndPublishElement(IkeyElement ikeyElement)
|
||||||
throws InterruptedException, PubSubException.NotALeafNodeException, XMPPException.XMPPErrorException,
|
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())
|
PepManager.getInstanceFor(connection())
|
||||||
.publish(IkeyConstants.SUBORDINATES_NODE, new PayloadItem<>(ikeyElement));
|
.publish(IkeyConstants.SUBORDINATES_NODE, new PayloadItem<>(element));
|
||||||
}
|
}
|
||||||
|
|
||||||
public IkeyElement fetchIkeyElementOf(EntityBareJid jid)
|
public IkeyElement fetchIkeyElementOf(EntityBareJid jid)
|
||||||
|
@ -201,7 +209,8 @@ public final class IkeyManager extends Manager {
|
||||||
throws IOException, UnsupportedSignatureAlgorithmException, PGPException {
|
throws IOException, UnsupportedSignatureAlgorithmException, PGPException {
|
||||||
IkeyRecord newRecord = elementToRecord(element);
|
IkeyRecord newRecord = elementToRecord(element);
|
||||||
if (isFromTheFuture(newRecord)) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,9 +316,9 @@ public final class IkeyManager extends Manager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isFromTheFuture(IkeyRecord record) {
|
private static boolean isFromTheFuture(IkeyRecord record) {
|
||||||
Date elementTimestamp = record.getTimestamp();
|
Date timestamp = record.getTimestamp();
|
||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
return elementTimestamp.after(now);
|
return timestamp.after(now);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean existsSameOrNewerRecord(IkeyRecord record) throws IOException {
|
private boolean existsSameOrNewerRecord(IkeyRecord record) throws IOException {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.mercury_im.messenger.core.viewmodel.account.detail;
|
package org.mercury_im.messenger.core.viewmodel.account.detail;
|
||||||
|
|
||||||
import org.bouncycastle.openpgp.PGPException;
|
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smackx.ikey.IkeyManager;
|
import org.jivesoftware.smackx.ikey.IkeyManager;
|
||||||
|
@ -88,7 +87,7 @@ public class AccountDetailsViewModel implements MercuryViewModel {
|
||||||
IkeyElement ikeyElement = syncCreateIkeyElement(accountId);
|
IkeyElement ikeyElement = syncCreateIkeyElement(accountId);
|
||||||
IkeyManager ikeyManager = IkeyManager.getInstanceFor(connectionManager.getConnection(accountId).getConnection());
|
IkeyManager ikeyManager = IkeyManager.getInstanceFor(connectionManager.getConnection(accountId).getConnection());
|
||||||
|
|
||||||
ikeyManager.publishIkeyElement(ikeyElement);
|
ikeyManager.storeAndPublishElement(ikeyElement);
|
||||||
})
|
})
|
||||||
.compose(schedulers.executeUiSafeCompletable())
|
.compose(schedulers.executeUiSafeCompletable())
|
||||||
.subscribe(
|
.subscribe(
|
||||||
|
@ -96,7 +95,7 @@ public class AccountDetailsViewModel implements MercuryViewModel {
|
||||||
e -> LOGGER.log(Level.SEVERE, "Error publishing ikey element:", e)));
|
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);
|
MercuryConnection connection = connectionManager.getConnection(accountId);
|
||||||
IkeyManager ikeyManager = ikeyInitializer.initFor(connection);
|
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()));
|
subordinateElements.add(new SubordinateElement("urn:xmpp:openpgp:0", u, fp.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
PGPSecretKeyRing secretKeys = openPgpRepository.loadSecretKeysOf(accountId, account.getJid())
|
PGPSecretKeyRing secretKeys = ikeyRepository.loadSecretKey(accountId)
|
||||||
.blockingGet().getSecretKeyRing(localFp.getKeyId());
|
.blockingFirst(new Optional<>())
|
||||||
|
.getItem();
|
||||||
|
|
||||||
IkeyElement ikeyElement = ikeyManager.createOxIkeyElement(secretKeys,
|
IkeyElement ikeyElement = ikeyManager.createOxIkeyElement(secretKeys,
|
||||||
new UnprotectedKeysProtector(), subordinateElements.toArray(new SubordinateElement[]{}));
|
new UnprotectedKeysProtector(), subordinateElements.toArray(new SubordinateElement[]{}));
|
||||||
|
|
Loading…
Reference in a new issue