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));
}
}
});
}
}
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);
}
}
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);
}
}
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;
}
Aggregations