Search in sources :

Example 11 with Jid

use of eu.siacs.conversations.xmpp.Jid in project Conversations by siacs.

the class AvatarService method get.

public Bitmap get(ListItem item, int size, boolean cachedOnly) {
    if (item instanceof RawBlockable) {
        return get(item.getDisplayName(), item.getJid().toEscapedString(), size, cachedOnly);
    } else if (item instanceof Contact) {
        return get((Contact) item, size, cachedOnly);
    } else if (item instanceof Bookmark) {
        Bookmark bookmark = (Bookmark) item;
        if (bookmark.getConversation() != null) {
            return get(bookmark.getConversation(), size, cachedOnly);
        } else {
            Jid jid = bookmark.getJid();
            Account account = bookmark.getAccount();
            Contact contact = jid == null ? null : account.getRoster().getContact(jid);
            if (contact != null && contact.getAvatarFilename() != null) {
                return get(contact, size, cachedOnly);
            }
            String seed = jid != null ? jid.asBareJid().toString() : null;
            return get(bookmark.getDisplayName(), seed, size, cachedOnly);
        }
    } else {
        String seed = item.getJid() != null ? item.getJid().asBareJid().toString() : null;
        return get(item.getDisplayName(), seed, size, cachedOnly);
    }
}
Also used : Account(eu.siacs.conversations.entities.Account) Bookmark(eu.siacs.conversations.entities.Bookmark) Jid(eu.siacs.conversations.xmpp.Jid) RawBlockable(eu.siacs.conversations.entities.RawBlockable) Contact(eu.siacs.conversations.entities.Contact)

Example 12 with Jid

use of eu.siacs.conversations.xmpp.Jid in project Conversations by siacs.

the class QuickConversationsService method considerSync.

private boolean considerSync(final Account account, final Map<String, PhoneNumberContact> contacts, final boolean forced) {
    final int hash = contacts.keySet().hashCode();
    Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": consider sync of " + hash);
    if (!mLastSyncAttempt.retry(hash) && !forced) {
        Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": do not attempt sync");
        return false;
    }
    mRunningSyncJobs.incrementAndGet();
    final Jid syncServer = Jid.of(API_DOMAIN);
    Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": sending phone list to " + syncServer);
    final List<Element> entries = new ArrayList<>();
    for (final PhoneNumberContact c : contacts.values()) {
        entries.add(new Element("entry").setAttribute("number", c.getPhoneNumber()));
    }
    final IqPacket query = new IqPacket(IqPacket.TYPE.GET);
    query.setTo(syncServer);
    final Element book = new Element("phone-book", Namespace.SYNCHRONIZATION).setChildren(entries);
    final String statusQuo = Entry.statusQuo(contacts.values(), account.getRoster().getWithSystemAccounts(PhoneNumberContact.class));
    book.setAttribute("ver", statusQuo);
    query.addChild(book);
    mLastSyncAttempt = Attempt.create(hash);
    service.sendIqPacket(account, query, (a, response) -> {
        if (response.getType() == IqPacket.TYPE.RESULT) {
            final Element phoneBook = response.findChild("phone-book", Namespace.SYNCHRONIZATION);
            if (phoneBook != null) {
                final List<Contact> withSystemAccounts = account.getRoster().getWithSystemAccounts(PhoneNumberContact.class);
                for (Entry entry : Entry.ofPhoneBook(phoneBook)) {
                    final PhoneNumberContact phoneContact = contacts.get(entry.getNumber());
                    if (phoneContact == null) {
                        continue;
                    }
                    for (final Jid jid : entry.getJids()) {
                        final Contact contact = account.getRoster().getContact(jid);
                        final boolean needsCacheClean = contact.setPhoneContact(phoneContact);
                        if (needsCacheClean) {
                            service.getAvatarService().clear(contact);
                        }
                        withSystemAccounts.remove(contact);
                    }
                }
                for (final Contact contact : withSystemAccounts) {
                    final boolean needsCacheClean = contact.unsetPhoneContact(PhoneNumberContact.class);
                    if (needsCacheClean) {
                        service.getAvatarService().clear(contact);
                    }
                }
            } else {
                Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": phone number contact list remains unchanged");
            }
        } else if (response.getType() == IqPacket.TYPE.TIMEOUT) {
            mLastSyncAttempt = Attempt.NULL;
        } else {
            Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": failed to sync contact list with api server");
        }
        mRunningSyncJobs.decrementAndGet();
        service.syncRoster(account);
        service.updateRosterUi();
    });
    return true;
}
Also used : Entry(eu.siacs.conversations.entities.Entry) Jid(eu.siacs.conversations.xmpp.Jid) PhoneNumberContact(eu.siacs.conversations.android.PhoneNumberContact) Element(eu.siacs.conversations.xml.Element) ArrayList(java.util.ArrayList) IqPacket(eu.siacs.conversations.xmpp.stanzas.IqPacket) PhoneNumberContact(eu.siacs.conversations.android.PhoneNumberContact) Contact(eu.siacs.conversations.entities.Contact)

Example 13 with Jid

use of eu.siacs.conversations.xmpp.Jid in project Conversations by siacs.

the class PushManagementService method registerPushTokenOnServer.

void registerPushTokenOnServer(final Account account) {
    Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": has push support");
    retrieveFcmInstanceToken(token -> {
        final String androidId = PhoneHelper.getAndroidId(mXmppConnectionService);
        final IqPacket packet = mXmppConnectionService.getIqGenerator().pushTokenToAppServer(getAppServer(), token, androidId);
        mXmppConnectionService.sendIqPacket(account, packet, (a, response) -> {
            final Data data = findResponseData(response);
            if (response.getType() == IqPacket.TYPE.RESULT && data != null) {
                try {
                    String node = data.getValue("node");
                    String secret = data.getValue("secret");
                    Jid jid = Jid.of(data.getValue("jid"));
                    if (node != null && secret != null) {
                        enablePushOnServer(a, jid, node, secret);
                    }
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                }
            } else {
                Log.d(Config.LOGTAG, a.getJid().asBareJid() + ": failed to enable push. invalid response from app server " + response);
            }
        });
    });
}
Also used : Jid(eu.siacs.conversations.xmpp.Jid) Data(eu.siacs.conversations.xmpp.forms.Data) IqPacket(eu.siacs.conversations.xmpp.stanzas.IqPacket)

Example 14 with Jid

use of eu.siacs.conversations.xmpp.Jid in project Conversations by siacs.

the class Entry method statusQuo.

private static String statusQuo(final List<Entry> entries) {
    Collections.sort(entries);
    StringBuilder builder = new StringBuilder();
    for (Entry entry : entries) {
        if (builder.length() != 0) {
            builder.append('\u001d');
        }
        builder.append(entry.getNumber());
        List<Jid> jids = entry.getJids();
        Collections.sort(jids);
        for (Jid jid : jids) {
            builder.append('\u001e');
            builder.append(jid.asBareJid().toEscapedString());
        }
    }
    @SuppressWarnings("deprecation") final byte[] sha1 = Hashing.sha1().hashString(builder.toString(), Charsets.UTF_8).asBytes();
    return new String(Base64.encode(sha1, Base64.DEFAULT)).trim();
}
Also used : Jid(eu.siacs.conversations.xmpp.Jid)

Example 15 with Jid

use of eu.siacs.conversations.xmpp.Jid in project Conversations by siacs.

the class AxolotlService method buildSessionFromPEP.

private ListenableFuture<XmppAxolotlSession> buildSessionFromPEP(final SignalProtocolAddress address, OnSessionBuildFromPep callback) {
    final SettableFuture<XmppAxolotlSession> sessionSettableFuture = SettableFuture.create();
    Log.i(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Building new session for " + address.toString());
    if (address.equals(getOwnAxolotlAddress())) {
        throw new AssertionError("We should NEVER build a session with ourselves. What happened here?!");
    }
    final Jid jid = Jid.of(address.getName());
    final boolean oneOfOurs = jid.asBareJid().equals(account.getJid().asBareJid());
    IqPacket bundlesPacket = mXmppConnectionService.getIqGenerator().retrieveBundlesForDevice(jid, address.getDeviceId());
    mXmppConnectionService.sendIqPacket(account, bundlesPacket, (account, packet) -> {
        if (packet.getType() == IqPacket.TYPE.TIMEOUT) {
            fetchStatusMap.put(address, FetchStatus.TIMEOUT);
            sessionSettableFuture.setException(new CryptoFailedException("Unable to build session. Timeout"));
        } else if (packet.getType() == IqPacket.TYPE.RESULT) {
            Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Received preKey IQ packet, processing...");
            final IqParser parser = mXmppConnectionService.getIqParser();
            final List<PreKeyBundle> preKeyBundleList = parser.preKeys(packet);
            final PreKeyBundle bundle = parser.bundle(packet);
            if (preKeyBundleList.isEmpty() || bundle == null) {
                Log.e(Config.LOGTAG, AxolotlService.getLogprefix(account) + "preKey IQ packet invalid: " + packet);
                fetchStatusMap.put(address, FetchStatus.ERROR);
                finishBuildingSessionsFromPEP(address);
                if (callback != null) {
                    callback.onSessionBuildFailed();
                }
                sessionSettableFuture.setException(new CryptoFailedException("Unable to build session. IQ Packet Invalid"));
                return;
            }
            Random random = new Random();
            final PreKeyBundle preKey = preKeyBundleList.get(random.nextInt(preKeyBundleList.size()));
            if (preKey == null) {
                // should never happen
                fetchStatusMap.put(address, FetchStatus.ERROR);
                finishBuildingSessionsFromPEP(address);
                if (callback != null) {
                    callback.onSessionBuildFailed();
                }
                sessionSettableFuture.setException(new CryptoFailedException("Unable to build session. No suitable PreKey found"));
                return;
            }
            final PreKeyBundle preKeyBundle = new PreKeyBundle(0, address.getDeviceId(), preKey.getPreKeyId(), preKey.getPreKey(), bundle.getSignedPreKeyId(), bundle.getSignedPreKey(), bundle.getSignedPreKeySignature(), bundle.getIdentityKey());
            try {
                SessionBuilder builder = new SessionBuilder(axolotlStore, address);
                builder.process(preKeyBundle);
                XmppAxolotlSession session = new XmppAxolotlSession(account, axolotlStore, address, bundle.getIdentityKey());
                sessions.put(address, session);
                if (Config.X509_VERIFICATION) {
                    // TODO; maybe inject callback in here too
                    sessionSettableFuture.setFuture(verifySessionWithPEP(session));
                } else {
                    FingerprintStatus status = getFingerprintTrust(CryptoHelper.bytesToHex(bundle.getIdentityKey().getPublicKey().serialize()));
                    FetchStatus fetchStatus;
                    if (status != null && status.isVerified()) {
                        fetchStatus = FetchStatus.SUCCESS_VERIFIED;
                    } else if (status != null && status.isTrusted()) {
                        fetchStatus = FetchStatus.SUCCESS_TRUSTED;
                    } else {
                        fetchStatus = FetchStatus.SUCCESS;
                    }
                    fetchStatusMap.put(address, fetchStatus);
                    finishBuildingSessionsFromPEP(address);
                    if (callback != null) {
                        callback.onSessionBuildSuccessful();
                    }
                    sessionSettableFuture.set(session);
                }
            } catch (UntrustedIdentityException | InvalidKeyException e) {
                Log.e(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Error building session for " + address + ": " + e.getClass().getName() + ", " + e.getMessage());
                fetchStatusMap.put(address, FetchStatus.ERROR);
                finishBuildingSessionsFromPEP(address);
                if (oneOfOurs && cleanedOwnDeviceIds.add(address.getDeviceId())) {
                    removeFromDeviceAnnouncement(address.getDeviceId());
                }
                if (callback != null) {
                    callback.onSessionBuildFailed();
                }
                sessionSettableFuture.setException(new CryptoFailedException(e));
            }
        } else {
            fetchStatusMap.put(address, FetchStatus.ERROR);
            Element error = packet.findChild("error");
            boolean itemNotFound = error != null && error.hasChild("item-not-found");
            Log.d(Config.LOGTAG, getLogprefix(account) + "Error received while building session:" + packet.findChild("error"));
            finishBuildingSessionsFromPEP(address);
            if (oneOfOurs && itemNotFound && cleanedOwnDeviceIds.add(address.getDeviceId())) {
                removeFromDeviceAnnouncement(address.getDeviceId());
            }
            if (callback != null) {
                callback.onSessionBuildFailed();
            }
            sessionSettableFuture.setException(new CryptoFailedException("Unable to build session. IQ Packet Error"));
        }
    });
    return sessionSettableFuture;
}
Also used : IqParser(eu.siacs.conversations.parser.IqParser) Jid(eu.siacs.conversations.xmpp.Jid) Element(eu.siacs.conversations.xml.Element) SessionBuilder(org.whispersystems.libsignal.SessionBuilder) IqPacket(eu.siacs.conversations.xmpp.stanzas.IqPacket) PreKeyBundle(org.whispersystems.libsignal.state.PreKeyBundle) Random(java.util.Random) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList)

Aggregations

Jid (eu.siacs.conversations.xmpp.Jid)106 Account (eu.siacs.conversations.entities.Account)35 Element (eu.siacs.conversations.xml.Element)24 Conversation (eu.siacs.conversations.entities.Conversation)22 Contact (eu.siacs.conversations.entities.Contact)17 InvalidJid (eu.siacs.conversations.xmpp.InvalidJid)16 IqPacket (eu.siacs.conversations.xmpp.stanzas.IqPacket)16 Intent (android.content.Intent)15 ArrayList (java.util.ArrayList)13 MucOptions (eu.siacs.conversations.entities.MucOptions)12 Bookmark (eu.siacs.conversations.entities.Bookmark)10 AxolotlService (eu.siacs.conversations.crypto.axolotl.AxolotlService)7 Message (eu.siacs.conversations.entities.Message)7 OnIqPacketReceived (eu.siacs.conversations.xmpp.OnIqPacketReceived)6 MessagePacket (eu.siacs.conversations.xmpp.stanzas.MessagePacket)6 Map (java.util.Map)6 XmppUri (eu.siacs.conversations.utils.XmppUri)5 XmppConnectionService (eu.siacs.conversations.services.XmppConnectionService)4 Avatar (eu.siacs.conversations.xmpp.pep.Avatar)4 HashMap (java.util.HashMap)4