Search in sources :

Example 1 with CryptoRoomMember

use of org.matrix.androidsdk.crypto.interfaces.CryptoRoomMember in project matrix-android-sdk by matrix-org.

the class MXCryptoImpl method onRoomMembership.

/**
 * Handle a change in the membership state of a member of a room.
 *
 * @param event the membership event causing the change
 */
private void onRoomMembership(final CryptoEvent event) {
    final IMXEncrypting alg;
    synchronized (mRoomEncryptors) {
        alg = mRoomEncryptors.get(event.getRoomId());
    }
    if (null == alg) {
        // No encrypting in this room
        return;
    }
    final String userId = event.getStateKey();
    final CryptoRoom room = mSession.getDataHandler().getRoom(event.getRoomId());
    CryptoRoomMember roomMember = room.getState().getMember(userId);
    if (null != roomMember) {
        final String membership = roomMember.getMembership();
        getEncryptingThreadHandler().post(new Runnable() {

            @Override
            public void run() {
                if (TextUtils.equals(membership, CryptoRoomMember.MEMBERSHIP_JOIN)) {
                    // make sure we are tracking the deviceList for this user.
                    getDeviceList().startTrackingDeviceList(Arrays.asList(userId));
                } else if (TextUtils.equals(membership, CryptoRoomMember.MEMBERSHIP_INVITE) && room.shouldEncryptForInvitedMembers() && mCryptoConfig.mEnableEncryptionForInvitedMembers) {
                    // track the deviceList for this invited user.
                    // Caution: there's a big edge case here in that federated servers do not
                    // know what other servers are in the room at the time they've been invited.
                    // They therefore will not send device updates if a user logs in whilst
                    // their state is invite.
                    getDeviceList().startTrackingDeviceList(Arrays.asList(userId));
                }
            }
        });
    }
}
Also used : IMXEncrypting(org.matrix.androidsdk.crypto.algorithms.IMXEncrypting) CryptoRoom(org.matrix.androidsdk.crypto.interfaces.CryptoRoom) CryptoRoomMember(org.matrix.androidsdk.crypto.interfaces.CryptoRoomMember)

Example 2 with CryptoRoomMember

use of org.matrix.androidsdk.crypto.interfaces.CryptoRoomMember in project matrix-android-sdk by matrix-org.

the class MXCryptoImpl method onCryptoEvent.

/**
 * Handle an m.room.encryption event.
 *
 * @param event the encryption event.
 */
private void onCryptoEvent(final CryptoEvent event) {
    final CryptoEventContent eventContent = event.getWireEventContent();
    final CryptoRoom room = mSession.getDataHandler().getRoom(event.getRoomId());
    // Check whether the event content must be encrypted for the invited members.
    boolean encryptForInvitedMembers = mCryptoConfig.mEnableEncryptionForInvitedMembers && room.shouldEncryptForInvitedMembers();
    ApiCallback<List<CryptoRoomMember>> callback = new ApiCallback<List<CryptoRoomMember>>() {

        @Override
        public void onSuccess(final List<CryptoRoomMember> info) {
            getEncryptingThreadHandler().post(new Runnable() {

                @Override
                public void run() {
                    setEncryptionInRoom(event.getRoomId(), eventContent.getAlgorithm(), true, info);
                }
            });
        }

        private void onError() {
            // Ensure setEncryption in room is done, even if there is a failure to fetch the room members
            getEncryptingThreadHandler().post(new Runnable() {

                @Override
                public void run() {
                    setEncryptionInRoom(event.getRoomId(), eventContent.getAlgorithm(), true, room.getState().getLoadedMembersCrypto());
                }
            });
        }

        @Override
        public void onNetworkError(Exception e) {
            Log.w(LOG_TAG, "[MXCrypto] onCryptoEvent: Warning: Unable to get all members from the HS. Fallback by using lazy-loaded members", e);
            onError();
        }

        @Override
        public void onMatrixError(MatrixError e) {
            Log.w(LOG_TAG, "[MXCrypto] onCryptoEvent: Warning: Unable to get all members from the HS. Fallback by using lazy-loaded members");
            onError();
        }

        @Override
        public void onUnexpectedError(Exception e) {
            Log.w(LOG_TAG, "[MXCrypto] onCryptoEvent: Warning: Unable to get all members from the HS. Fallback by using lazy-loaded members", e);
            onError();
        }
    };
    if (encryptForInvitedMembers) {
        room.getActiveMembersAsyncCrypto(callback);
    } else {
        room.getJoinedMembersAsyncCrypto(callback);
    }
}
Also used : CryptoRoom(org.matrix.androidsdk.crypto.interfaces.CryptoRoom) CryptoRoomMember(org.matrix.androidsdk.crypto.interfaces.CryptoRoomMember) SimpleApiCallback(org.matrix.androidsdk.core.callback.SimpleApiCallback) ApiCallback(org.matrix.androidsdk.core.callback.ApiCallback) CryptoEventContent(org.matrix.androidsdk.crypto.interfaces.CryptoEventContent) MXDeviceList(org.matrix.androidsdk.crypto.MXDeviceList) List(java.util.List) ArrayList(java.util.ArrayList) MatrixError(org.matrix.androidsdk.core.model.MatrixError) MXDecryptionException(org.matrix.androidsdk.crypto.MXDecryptionException)

Example 3 with CryptoRoomMember

use of org.matrix.androidsdk.crypto.interfaces.CryptoRoomMember in project matrix-android-sdk by matrix-org.

the class MXCryptoImpl method encryptEventContent.

/**
 * Encrypt an event content according to the configuration of the room.
 *
 * @param eventContent the content of the event.
 * @param eventType    the type of the event.
 * @param room         the room the event will be sent.
 * @param callback     the asynchronous callback
 */
@Override
public void encryptEventContent(final JsonElement eventContent, final String eventType, final CryptoRoom room, final ApiCallback<MXEncryptEventContentResult> callback) {
    // wait that the crypto is really started
    if (!isStarted()) {
        Log.d(LOG_TAG, "## encryptEventContent() : wait after e2e init");
        start(false, new ApiCallback<Void>() {

            @Override
            public void onSuccess(Void info) {
                encryptEventContent(eventContent, eventType, room, callback);
            }

            @Override
            public void onNetworkError(Exception e) {
                Log.e(LOG_TAG, "## encryptEventContent() : onNetworkError while waiting to start e2e : " + e.getMessage(), e);
                if (null != callback) {
                    callback.onNetworkError(e);
                }
            }

            @Override
            public void onMatrixError(MatrixError e) {
                Log.e(LOG_TAG, "## encryptEventContent() : onMatrixError while waiting to start e2e : " + e.getMessage());
                if (null != callback) {
                    callback.onMatrixError(e);
                }
            }

            @Override
            public void onUnexpectedError(Exception e) {
                Log.e(LOG_TAG, "## encryptEventContent() : onUnexpectedError while waiting to start e2e : " + e.getMessage(), e);
                if (null != callback) {
                    callback.onUnexpectedError(e);
                }
            }
        });
        return;
    }
    final ApiCallback<List<CryptoRoomMember>> apiCallback = new SimpleApiCallback<List<CryptoRoomMember>>(callback) {

        @Override
        public void onSuccess(final List<CryptoRoomMember> members) {
            // just as you are sending a secret message?
            final List<String> userIds = new ArrayList<>();
            for (CryptoRoomMember m : members) {
                userIds.add(m.getUserId());
            }
            getEncryptingThreadHandler().post(new Runnable() {

                @Override
                public void run() {
                    IMXEncrypting alg;
                    synchronized (mRoomEncryptors) {
                        alg = mRoomEncryptors.get(room.getRoomId());
                    }
                    if (null == alg) {
                        String algorithm = room.getState().encryptionAlgorithm();
                        if (null != algorithm) {
                            if (setEncryptionInRoom(room.getRoomId(), algorithm, false, members)) {
                                synchronized (mRoomEncryptors) {
                                    alg = mRoomEncryptors.get(room.getRoomId());
                                }
                            }
                        }
                    }
                    if (null != alg) {
                        final long t0 = System.currentTimeMillis();
                        Log.d(LOG_TAG, "## encryptEventContent() starts");
                        alg.encryptEventContent(eventContent, eventType, userIds, new ApiCallback<JsonElement>() {

                            @Override
                            public void onSuccess(final JsonElement encryptedContent) {
                                Log.d(LOG_TAG, "## encryptEventContent() : succeeds after " + (System.currentTimeMillis() - t0) + " ms");
                                if (null != callback) {
                                    callback.onSuccess(new MXEncryptEventContentResult(encryptedContent, CryptoEvent.EVENT_TYPE_MESSAGE_ENCRYPTED));
                                }
                            }

                            @Override
                            public void onNetworkError(final Exception e) {
                                Log.e(LOG_TAG, "## encryptEventContent() : onNetworkError " + e.getMessage(), e);
                                if (null != callback) {
                                    callback.onNetworkError(e);
                                }
                            }

                            @Override
                            public void onMatrixError(final MatrixError e) {
                                Log.e(LOG_TAG, "## encryptEventContent() : onMatrixError " + e.getMessage());
                                if (null != callback) {
                                    callback.onMatrixError(e);
                                }
                            }

                            @Override
                            public void onUnexpectedError(final Exception e) {
                                Log.e(LOG_TAG, "## encryptEventContent() : onUnexpectedError " + e.getMessage(), e);
                                if (null != callback) {
                                    callback.onUnexpectedError(e);
                                }
                            }
                        });
                    } else {
                        final String algorithm = room.getState().encryptionAlgorithm();
                        final String reason = String.format(MXCryptoError.UNABLE_TO_ENCRYPT_REASON, (null == algorithm) ? MXCryptoError.NO_MORE_ALGORITHM_REASON : algorithm);
                        Log.e(LOG_TAG, "## encryptEventContent() : " + reason);
                        if (null != callback) {
                            getUIHandler().post(new Runnable() {

                                @Override
                                public void run() {
                                    callback.onMatrixError(new MXCryptoError(MXCryptoError.UNABLE_TO_ENCRYPT_ERROR_CODE, MXCryptoError.UNABLE_TO_ENCRYPT, reason));
                                }
                            });
                        }
                    }
                }
            });
        }
    };
    // Check whether the event content must be encrypted for the invited members.
    boolean encryptForInvitedMembers = mCryptoConfig.mEnableEncryptionForInvitedMembers && room.shouldEncryptForInvitedMembers();
    if (encryptForInvitedMembers) {
        room.getActiveMembersAsyncCrypto(apiCallback);
    } else {
        room.getJoinedMembersAsyncCrypto(apiCallback);
    }
}
Also used : IMXEncrypting(org.matrix.androidsdk.crypto.algorithms.IMXEncrypting) CryptoRoomMember(org.matrix.androidsdk.crypto.interfaces.CryptoRoomMember) SimpleApiCallback(org.matrix.androidsdk.core.callback.SimpleApiCallback) ApiCallback(org.matrix.androidsdk.core.callback.ApiCallback) ArrayList(java.util.ArrayList) MXDecryptionException(org.matrix.androidsdk.crypto.MXDecryptionException) MXEncryptEventContentResult(org.matrix.androidsdk.crypto.data.MXEncryptEventContentResult) JsonElement(com.google.gson.JsonElement) MXDeviceList(org.matrix.androidsdk.crypto.MXDeviceList) List(java.util.List) ArrayList(java.util.ArrayList) MatrixError(org.matrix.androidsdk.core.model.MatrixError) SimpleApiCallback(org.matrix.androidsdk.core.callback.SimpleApiCallback) MXCryptoError(org.matrix.androidsdk.crypto.MXCryptoError)

Example 4 with CryptoRoomMember

use of org.matrix.androidsdk.crypto.interfaces.CryptoRoomMember in project matrix-android-sdk by matrix-org.

the class MXCryptoImpl method setEncryptionInRoom.

/**
 * Configure a room to use encryption.
 * This method must be called in getEncryptingThreadHandler
 *
 * @param roomId             the room id to enable encryption in.
 * @param algorithm          the encryption config for the room.
 * @param inhibitDeviceQuery true to suppress device list query for users in the room (for now)
 * @param members            list of members to start tracking their devices
 * @return true if the operation succeeds.
 */
private boolean setEncryptionInRoom(String roomId, String algorithm, boolean inhibitDeviceQuery, List<CryptoRoomMember> members) {
    if (hasBeenReleased()) {
        return false;
    }
    // If we already have encryption in this room, we should ignore this event
    // (for now at least. Maybe we should alert the user somehow?)
    String existingAlgorithm = mCryptoStore.getRoomAlgorithm(roomId);
    if (!TextUtils.isEmpty(existingAlgorithm) && !TextUtils.equals(existingAlgorithm, algorithm)) {
        Log.e(LOG_TAG, "## setEncryptionInRoom() : Ignoring m.room.encryption event which requests a change of config in " + roomId);
        return false;
    }
    Class<IMXEncrypting> encryptingClass = MXCryptoAlgorithms.sharedAlgorithms().encryptorClassForAlgorithm(algorithm);
    if (null == encryptingClass) {
        Log.e(LOG_TAG, "## setEncryptionInRoom() : Unable to encrypt with " + algorithm);
        return false;
    }
    mCryptoStore.storeRoomAlgorithm(roomId, algorithm);
    IMXEncrypting alg;
    try {
        Constructor<?> ctor = encryptingClass.getConstructors()[0];
        alg = (IMXEncrypting) ctor.newInstance();
    } catch (Exception e) {
        Log.e(LOG_TAG, "## setEncryptionInRoom() : fail to load the class", e);
        return false;
    }
    alg.initWithMatrixSession(mSession, this, roomId);
    synchronized (mRoomEncryptors) {
        mRoomEncryptors.put(roomId, alg);
    }
    // we just invalidate everyone in the room.
    if (null == existingAlgorithm) {
        Log.d(LOG_TAG, "Enabling encryption in " + roomId + " for the first time; invalidating device lists for all users therein");
        List<String> userIds = new ArrayList<>();
        for (CryptoRoomMember m : members) {
            userIds.add(m.getUserId());
        }
        getDeviceList().startTrackingDeviceList(userIds);
        if (!inhibitDeviceQuery) {
            getDeviceList().refreshOutdatedDeviceLists();
        }
    }
    return true;
}
Also used : IMXEncrypting(org.matrix.androidsdk.crypto.algorithms.IMXEncrypting) CryptoRoomMember(org.matrix.androidsdk.crypto.interfaces.CryptoRoomMember) ArrayList(java.util.ArrayList) MXDecryptionException(org.matrix.androidsdk.crypto.MXDecryptionException)

Aggregations

CryptoRoomMember (org.matrix.androidsdk.crypto.interfaces.CryptoRoomMember)4 ArrayList (java.util.ArrayList)3 MXDecryptionException (org.matrix.androidsdk.crypto.MXDecryptionException)3 IMXEncrypting (org.matrix.androidsdk.crypto.algorithms.IMXEncrypting)3 List (java.util.List)2 ApiCallback (org.matrix.androidsdk.core.callback.ApiCallback)2 SimpleApiCallback (org.matrix.androidsdk.core.callback.SimpleApiCallback)2 MatrixError (org.matrix.androidsdk.core.model.MatrixError)2 MXDeviceList (org.matrix.androidsdk.crypto.MXDeviceList)2 CryptoRoom (org.matrix.androidsdk.crypto.interfaces.CryptoRoom)2 JsonElement (com.google.gson.JsonElement)1 MXCryptoError (org.matrix.androidsdk.crypto.MXCryptoError)1 MXEncryptEventContentResult (org.matrix.androidsdk.crypto.data.MXEncryptEventContentResult)1 CryptoEventContent (org.matrix.androidsdk.crypto.interfaces.CryptoEventContent)1