forked from GitHub-Mirror/riotX-android
Convert MXUsersDevicesMap to kotlin
This commit is contained in:
parent
0ca9a5f68b
commit
f789fb275d
@ -1039,10 +1039,10 @@ internal class CryptoManager @Inject constructor(
|
|||||||
for (userId in userIds) {
|
for (userId in userIds) {
|
||||||
val deviceIds = devicesInRoom.getUserDeviceIds(userId)
|
val deviceIds = devicesInRoom.getUserDeviceIds(userId)
|
||||||
for (deviceId in deviceIds!!) {
|
for (deviceId in deviceIds!!) {
|
||||||
val deviceInfo = devicesInRoom.getObject(deviceId, userId)
|
val deviceInfo = devicesInRoom.getObject(userId, deviceId)
|
||||||
|
|
||||||
if (deviceInfo!!.isUnknown) {
|
if (deviceInfo?.isUnknown == true) {
|
||||||
unknownDevices.setObject(deviceInfo, userId, deviceId)
|
unknownDevices.setObject(userId, deviceId, deviceInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,7 +221,7 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM
|
|||||||
Timber.v("Device list for $userId now up to date")
|
Timber.v("Device list for $userId now up to date")
|
||||||
}
|
}
|
||||||
// And the response result
|
// And the response result
|
||||||
usersDevicesInfoMap.setObjects(devices, userId)
|
usersDevicesInfoMap.setObjects(userId, devices)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cryptoStore.saveDeviceTrackingStatuses(deviceTrackingStatuses)
|
cryptoStore.saveDeviceTrackingStatuses(deviceTrackingStatuses)
|
||||||
@ -239,7 +239,7 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM
|
|||||||
*/
|
*/
|
||||||
suspend fun downloadKeys(userIds: List<String>?, forceDownload: Boolean): Try<MXUsersDevicesMap<MXDeviceInfo>> {
|
suspend fun downloadKeys(userIds: List<String>?, forceDownload: Boolean): Try<MXUsersDevicesMap<MXDeviceInfo>> {
|
||||||
Timber.v("## downloadKeys() : forceDownload $forceDownload : $userIds")
|
Timber.v("## downloadKeys() : forceDownload $forceDownload : $userIds")
|
||||||
// Map from userid -> deviceid -> DeviceInfo
|
// Map from userId -> deviceId -> MXDeviceInfo
|
||||||
val stored = MXUsersDevicesMap<MXDeviceInfo>()
|
val stored = MXUsersDevicesMap<MXDeviceInfo>()
|
||||||
|
|
||||||
// List of user ids we need to download keys for
|
// List of user ids we need to download keys for
|
||||||
@ -258,7 +258,7 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM
|
|||||||
val devices = cryptoStore.getUserDevices(userId)
|
val devices = cryptoStore.getUserDevices(userId)
|
||||||
// should always be true
|
// should always be true
|
||||||
if (devices != null) {
|
if (devices != null) {
|
||||||
stored.setObjects(devices, userId)
|
stored.setObjects(userId, devices)
|
||||||
} else {
|
} else {
|
||||||
downloadUsers.add(userId)
|
downloadUsers.add(userId)
|
||||||
}
|
}
|
||||||
|
@ -286,7 +286,7 @@ internal class OutgoingRoomKeyRequestManager @Inject constructor(
|
|||||||
|
|
||||||
for (recipient in recipients) {
|
for (recipient in recipients) {
|
||||||
// TODO Change this two hard coded key to something better
|
// TODO Change this two hard coded key to something better
|
||||||
contentMap.setObject(message, recipient["userId"], recipient["deviceId"])
|
contentMap.setObject(recipient["userId"], recipient["deviceId"], message)
|
||||||
}
|
}
|
||||||
|
|
||||||
sendToDeviceTask.configureWith(SendToDeviceTask.Params(EventType.ROOM_KEY_REQUEST, contentMap, transactionId))
|
sendToDeviceTask.configureWith(SendToDeviceTask.Params(EventType.ROOM_KEY_REQUEST, contentMap, transactionId))
|
||||||
|
@ -53,7 +53,7 @@ internal class EnsureOlmSessionsForDevicesAction @Inject constructor(private val
|
|||||||
}
|
}
|
||||||
|
|
||||||
val olmSessionResult = MXOlmSessionResult(deviceInfo, sessionId)
|
val olmSessionResult = MXOlmSessionResult(deviceInfo, sessionId)
|
||||||
results.setObject(olmSessionResult, userId, deviceId)
|
results.setObject(userId, deviceId, olmSessionResult)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,12 +90,12 @@ internal class EnsureOlmSessionsForDevicesAction @Inject constructor(private val
|
|||||||
val deviceIds = it.getUserDeviceIds(userId)
|
val deviceIds = it.getUserDeviceIds(userId)
|
||||||
if (null != deviceIds) {
|
if (null != deviceIds) {
|
||||||
for (deviceId in deviceIds) {
|
for (deviceId in deviceIds) {
|
||||||
val olmSessionResult = results.getObject(deviceId, userId)
|
val olmSessionResult = results.getObject(userId, deviceId)
|
||||||
if (olmSessionResult!!.sessionId != null) {
|
if (olmSessionResult!!.sessionId != null) {
|
||||||
// We already have a result for this device
|
// We already have a result for this device
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
val key = it.getObject(deviceId, userId)
|
val key = it.getObject(userId, deviceId)
|
||||||
if (key?.type == oneTimeKeyAlgorithm) {
|
if (key?.type == oneTimeKeyAlgorithm) {
|
||||||
oneTimeKey = key
|
oneTimeKey = key
|
||||||
}
|
}
|
||||||
|
@ -309,7 +309,7 @@ internal class MXMegolmDecryption(private val credentials: Credentials,
|
|||||||
.handle(devicesByUser)
|
.handle(devicesByUser)
|
||||||
.flatMap {
|
.flatMap {
|
||||||
val body = request.requestBody
|
val body = request.requestBody
|
||||||
val olmSessionResult = it.getObject(deviceId, userId)
|
val olmSessionResult = it.getObject(userId, deviceId)
|
||||||
if (olmSessionResult?.sessionId == null) {
|
if (olmSessionResult?.sessionId == null) {
|
||||||
// no session with this device, probably because there
|
// no session with this device, probably because there
|
||||||
// were no one-time keys.
|
// were no one-time keys.
|
||||||
@ -325,7 +325,7 @@ internal class MXMegolmDecryption(private val credentials: Credentials,
|
|||||||
|
|
||||||
val encodedPayload = messageEncrypter.encryptMessage(payloadJson, Arrays.asList(deviceInfo))
|
val encodedPayload = messageEncrypter.encryptMessage(payloadJson, Arrays.asList(deviceInfo))
|
||||||
val sendToDeviceMap = MXUsersDevicesMap<Any>()
|
val sendToDeviceMap = MXUsersDevicesMap<Any>()
|
||||||
sendToDeviceMap.setObject(encodedPayload, userId, deviceId)
|
sendToDeviceMap.setObject(userId, deviceId, encodedPayload)
|
||||||
Timber.v("## shareKeysWithDevice() : sending to $userId:$deviceId")
|
Timber.v("## shareKeysWithDevice() : sending to $userId:$deviceId")
|
||||||
val sendToDeviceParams = SendToDeviceTask.Params(EventType.ENCRYPTED, sendToDeviceMap)
|
val sendToDeviceParams = SendToDeviceTask.Params(EventType.ENCRYPTED, sendToDeviceMap)
|
||||||
sendToDeviceTask.execute(sendToDeviceParams)
|
sendToDeviceTask.execute(sendToDeviceParams)
|
||||||
|
@ -118,8 +118,8 @@ internal class MXMegolmEncryption(
|
|||||||
for (userId in userIds) {
|
for (userId in userIds) {
|
||||||
val deviceIds = devicesInRoom.getUserDeviceIds(userId)
|
val deviceIds = devicesInRoom.getUserDeviceIds(userId)
|
||||||
for (deviceId in deviceIds!!) {
|
for (deviceId in deviceIds!!) {
|
||||||
val deviceInfo = devicesInRoom.getObject(deviceId, userId)
|
val deviceInfo = devicesInRoom.getObject(userId, deviceId)
|
||||||
if (null == safeSession.sharedWithDevices.getObject(deviceId, userId)) {
|
if (deviceInfo != null && null == safeSession.sharedWithDevices.getObject(userId, deviceId)) {
|
||||||
if (!shareMap.containsKey(userId)) {
|
if (!shareMap.containsKey(userId)) {
|
||||||
shareMap[userId] = ArrayList()
|
shareMap[userId] = ArrayList()
|
||||||
}
|
}
|
||||||
@ -201,7 +201,7 @@ internal class MXMegolmEncryption(
|
|||||||
for (userId in userIds) {
|
for (userId in userIds) {
|
||||||
val devicesToShareWith = devicesByUser[userId]
|
val devicesToShareWith = devicesByUser[userId]
|
||||||
for ((deviceID) in devicesToShareWith!!) {
|
for ((deviceID) in devicesToShareWith!!) {
|
||||||
val sessionResult = it.getObject(deviceID, userId)
|
val sessionResult = it.getObject(userId, deviceID)
|
||||||
if (sessionResult?.sessionId == null) {
|
if (sessionResult?.sessionId == null) {
|
||||||
// no session with this device, probably because there
|
// no session with this device, probably because there
|
||||||
// were no one-time keys.
|
// were no one-time keys.
|
||||||
@ -218,7 +218,7 @@ internal class MXMegolmEncryption(
|
|||||||
}
|
}
|
||||||
Timber.v("## shareUserDevicesKey() : Sharing keys with device $userId:$deviceID")
|
Timber.v("## shareUserDevicesKey() : Sharing keys with device $userId:$deviceID")
|
||||||
//noinspection ArraysAsListWithZeroOrOneArgument,ArraysAsListWithZeroOrOneArgument
|
//noinspection ArraysAsListWithZeroOrOneArgument,ArraysAsListWithZeroOrOneArgument
|
||||||
contentMap.setObject(messageEncrypter.encryptMessage(payload, Arrays.asList(sessionResult.deviceInfo)), userId, deviceID)
|
contentMap.setObject(userId, deviceID, messageEncrypter.encryptMessage(payload, Arrays.asList(sessionResult.deviceInfo)))
|
||||||
haveTargets = true
|
haveTargets = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -239,7 +239,7 @@ internal class MXMegolmEncryption(
|
|||||||
for (userId in devicesByUser.keys) {
|
for (userId in devicesByUser.keys) {
|
||||||
val devicesToShareWith = devicesByUser[userId]
|
val devicesToShareWith = devicesByUser[userId]
|
||||||
for ((deviceId) in devicesToShareWith!!) {
|
for ((deviceId) in devicesToShareWith!!) {
|
||||||
session.sharedWithDevices.setObject(chainIndex, userId, deviceId)
|
session.sharedWithDevices.setObject(userId, deviceId, chainIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Unit
|
Unit
|
||||||
@ -303,10 +303,10 @@ internal class MXMegolmEncryption(
|
|||||||
for (userId in it.userIds) {
|
for (userId in it.userIds) {
|
||||||
val deviceIds = it.getUserDeviceIds(userId) ?: continue
|
val deviceIds = it.getUserDeviceIds(userId) ?: continue
|
||||||
for (deviceId in deviceIds) {
|
for (deviceId in deviceIds) {
|
||||||
val deviceInfo = it.getObject(deviceId, userId) ?: continue
|
val deviceInfo = it.getObject(userId, deviceId) ?: continue
|
||||||
if (warnOnUnknownDevicesRepository.warnOnUnknownDevices() && deviceInfo.isUnknown) {
|
if (warnOnUnknownDevicesRepository.warnOnUnknownDevices() && deviceInfo.isUnknown) {
|
||||||
// The device is not yet known by the user
|
// The device is not yet known by the user
|
||||||
unknownDevices.setObject(deviceInfo, userId, deviceId)
|
unknownDevices.setObject(userId, deviceId, deviceInfo)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (deviceInfo.isBlocked) {
|
if (deviceInfo.isBlocked) {
|
||||||
@ -322,7 +322,7 @@ internal class MXMegolmEncryption(
|
|||||||
// Don't bother sending to ourself
|
// Don't bother sending to ourself
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
devicesInRoom.setObject(deviceInfo, userId, deviceId)
|
devicesInRoom.setObject(userId, deviceId, deviceInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (unknownDevices.isEmpty) {
|
if (unknownDevices.isEmpty) {
|
||||||
|
@ -64,7 +64,7 @@ internal class MXOutboundSessionInfo(
|
|||||||
val deviceIds = sharedWithDevices.getUserDeviceIds(userId)
|
val deviceIds = sharedWithDevices.getUserDeviceIds(userId)
|
||||||
|
|
||||||
for (deviceId in deviceIds!!) {
|
for (deviceId in deviceIds!!) {
|
||||||
if (null == devicesInRoom.getObject(deviceId, userId)) {
|
if (null == devicesInRoom.getObject(userId, deviceId)) {
|
||||||
Timber.v("## sharedWithTooManyDevices() : Starting new session because we shared with $userId:$deviceId")
|
Timber.v("## sharedWithTooManyDevices() : Starting new session because we shared with $userId:$deviceId")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -1,186 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2016 OpenMarket Ltd
|
|
||||||
* Copyright 2018 New Vector Ltd
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package im.vector.matrix.android.internal.crypto.model;
|
|
||||||
|
|
||||||
import android.text.TextUtils;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class MXUsersDevicesMap<E> implements Serializable {
|
|
||||||
|
|
||||||
// The device keys as returned by the homeserver: a map of a map (userId -> deviceId -> Object).
|
|
||||||
private final Map<String, Map<String, E>> mMap = new HashMap<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the inner map
|
|
||||||
*/
|
|
||||||
public Map<String, Map<String, E>> getMap() {
|
|
||||||
return mMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor constructor
|
|
||||||
*/
|
|
||||||
public MXUsersDevicesMap() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The constructor
|
|
||||||
*
|
|
||||||
* @param map the map
|
|
||||||
*/
|
|
||||||
public MXUsersDevicesMap(Map<String, Map<String, E>> map) {
|
|
||||||
if (null != map) {
|
|
||||||
Set<String> keys = map.keySet();
|
|
||||||
|
|
||||||
for (String key : keys) {
|
|
||||||
mMap.put(key, new HashMap<>(map.get(key)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return a deep copy
|
|
||||||
*/
|
|
||||||
public MXUsersDevicesMap<E> deepCopy() {
|
|
||||||
MXUsersDevicesMap<E> copy = new MXUsersDevicesMap<>();
|
|
||||||
|
|
||||||
Set<String> keys = mMap.keySet();
|
|
||||||
|
|
||||||
for (String key : keys) {
|
|
||||||
copy.mMap.put(key, new HashMap<>(mMap.get(key)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the user Ids
|
|
||||||
*/
|
|
||||||
public List<String> getUserIds() {
|
|
||||||
return new ArrayList<>(mMap.keySet());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides the device ids list for an user id
|
|
||||||
*
|
|
||||||
* @param userId the user id
|
|
||||||
* @return the device ids list
|
|
||||||
*/
|
|
||||||
public List<String> getUserDeviceIds(String userId) {
|
|
||||||
if (!TextUtils.isEmpty(userId) && mMap.containsKey(userId)) {
|
|
||||||
return new ArrayList<>(mMap.get(userId).keySet());
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides the object for a device id and an user Id
|
|
||||||
*
|
|
||||||
* @param deviceId the device id
|
|
||||||
* @param userId the object id
|
|
||||||
* @return the object
|
|
||||||
*/
|
|
||||||
public E getObject(String deviceId, String userId) {
|
|
||||||
if (!TextUtils.isEmpty(userId) && mMap.containsKey(userId) && !TextUtils.isEmpty(deviceId)) {
|
|
||||||
return mMap.get(userId).get(deviceId);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set an object for a dedicated user Id and device Id
|
|
||||||
*
|
|
||||||
* @param object the object to set
|
|
||||||
* @param userId the user Id
|
|
||||||
* @param deviceId the device id
|
|
||||||
*/
|
|
||||||
public void setObject(E object, String userId, String deviceId) {
|
|
||||||
if ((null != object) && !TextUtils.isEmpty(userId) && !TextUtils.isEmpty(deviceId)) {
|
|
||||||
Map<String, E> subMap = mMap.get(userId);
|
|
||||||
|
|
||||||
if (null == subMap) {
|
|
||||||
subMap = new HashMap<>();
|
|
||||||
mMap.put(userId, subMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
subMap.put(deviceId, object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Defines the objects map for an user Id
|
|
||||||
*
|
|
||||||
* @param objectsPerDevices the objects maps
|
|
||||||
* @param userId the user id
|
|
||||||
*/
|
|
||||||
public void setObjects(Map<String, E> objectsPerDevices, String userId) {
|
|
||||||
if (!TextUtils.isEmpty(userId)) {
|
|
||||||
if (null == objectsPerDevices) {
|
|
||||||
mMap.remove(userId);
|
|
||||||
} else {
|
|
||||||
mMap.put(userId, new HashMap<>(objectsPerDevices));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes objects for a dedicated user
|
|
||||||
*
|
|
||||||
* @param userId the user id.
|
|
||||||
*/
|
|
||||||
public void removeUserObjects(String userId) {
|
|
||||||
if (!TextUtils.isEmpty(userId)) {
|
|
||||||
mMap.remove(userId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clear the internal dictionary
|
|
||||||
*/
|
|
||||||
public void removeAllObjects() {
|
|
||||||
mMap.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add entries from another MXUsersDevicesMap
|
|
||||||
*
|
|
||||||
* @param other the other one
|
|
||||||
*/
|
|
||||||
public void addEntriesFromMap(MXUsersDevicesMap<E> other) {
|
|
||||||
if (null != other) {
|
|
||||||
mMap.putAll(other.getMap());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEmpty() {
|
|
||||||
return mMap.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "MXUsersDevicesMap " + mMap.toString();
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.matrix.android.internal.crypto.model
|
||||||
|
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class MXUsersDevicesMap<E> {
|
||||||
|
|
||||||
|
// A map of maps (userId -> (deviceId -> Object)).
|
||||||
|
val map = HashMap<String /* userId */, HashMap<String /* deviceId */, E>>()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the user Ids
|
||||||
|
*/
|
||||||
|
val userIds: List<String>
|
||||||
|
get() = ArrayList(map.keys)
|
||||||
|
|
||||||
|
val isEmpty: Boolean
|
||||||
|
get() = map.isEmpty()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the device ids list for a user id
|
||||||
|
* FIXME Should maybe return emptyList and not null, to avoid many !! in the code
|
||||||
|
*
|
||||||
|
* @param userId the user id
|
||||||
|
* @return the device ids list
|
||||||
|
*/
|
||||||
|
fun getUserDeviceIds(userId: String?): List<String>? {
|
||||||
|
return if (userId?.isNotBlank() == true && map.containsKey(userId)) {
|
||||||
|
map[userId]!!.keys.toList()
|
||||||
|
} else null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the object for a device id and a user Id
|
||||||
|
*
|
||||||
|
* @param deviceId the device id
|
||||||
|
* @param userId the object id
|
||||||
|
* @return the object
|
||||||
|
*/
|
||||||
|
fun getObject(userId: String?, deviceId: String?): E? {
|
||||||
|
return if (userId?.isNotBlank() == true && deviceId?.isNotBlank() == true && map.containsKey(userId)) {
|
||||||
|
map[userId]!![deviceId]
|
||||||
|
} else null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set an object for a dedicated user Id and device Id
|
||||||
|
*
|
||||||
|
* @param userId the user Id
|
||||||
|
* @param deviceId the device id
|
||||||
|
* @param o the object to set
|
||||||
|
*/
|
||||||
|
fun setObject(userId: String?, deviceId: String?, o: E?) {
|
||||||
|
if (null != o && userId?.isNotBlank() == true && deviceId?.isNotBlank() == true) {
|
||||||
|
if (map[userId] == null) {
|
||||||
|
map[userId] = HashMap()
|
||||||
|
}
|
||||||
|
|
||||||
|
map[userId]!![deviceId] = o
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the objects map for a user Id
|
||||||
|
*
|
||||||
|
* @param objectsPerDevices the objects maps
|
||||||
|
* @param userId the user id
|
||||||
|
*/
|
||||||
|
fun setObjects(userId: String?, objectsPerDevices: Map<String, E>?) {
|
||||||
|
if (userId?.isNotBlank() == true) {
|
||||||
|
if (null == objectsPerDevices) {
|
||||||
|
map.remove(userId)
|
||||||
|
} else {
|
||||||
|
map[userId] = HashMap(objectsPerDevices)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes objects for a dedicated user
|
||||||
|
*
|
||||||
|
* @param userId the user id.
|
||||||
|
*/
|
||||||
|
fun removeUserObjects(userId: String?) {
|
||||||
|
if (userId?.isNotBlank() == true) {
|
||||||
|
map.remove(userId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the internal dictionary
|
||||||
|
*/
|
||||||
|
fun removeAllObjects() {
|
||||||
|
map.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add entries from another MXUsersDevicesMap
|
||||||
|
*
|
||||||
|
* @param other the other one
|
||||||
|
*/
|
||||||
|
fun addEntriesFromMap(other: MXUsersDevicesMap<E>?) {
|
||||||
|
if (null != other) {
|
||||||
|
map.putAll(other.map)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "MXUsersDevicesMap $map"
|
||||||
|
}
|
||||||
|
}
|
@ -18,8 +18,9 @@ package im.vector.matrix.android.internal.crypto.model.rest
|
|||||||
|
|
||||||
class SendToDeviceBody {
|
class SendToDeviceBody {
|
||||||
|
|
||||||
// `Any` should implement SendToDeviceObject, but we cannot use interface here because of Gson serialization
|
|
||||||
/**
|
/**
|
||||||
|
* `Any` should implement [SendToDeviceObject], but we cannot use interface here because of Json serialization
|
||||||
|
*
|
||||||
* The messages to send. A map from user ID, to a map from device ID to message body.
|
* The messages to send. A map from user ID, to a map from device ID to message body.
|
||||||
* The device ID may also be *, meaning all known devices for the user.
|
* The device ID may also be *, meaning all known devices for the user.
|
||||||
*/
|
*/
|
||||||
|
@ -25,7 +25,6 @@ import im.vector.matrix.android.internal.crypto.model.rest.KeysClaimResponse
|
|||||||
import im.vector.matrix.android.internal.network.executeRequest
|
import im.vector.matrix.android.internal.network.executeRequest
|
||||||
import im.vector.matrix.android.internal.task.Task
|
import im.vector.matrix.android.internal.task.Task
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.*
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal interface ClaimOneTimeKeysForUsersDeviceTask : Task<ClaimOneTimeKeysForUsersDeviceTask.Params, MXUsersDevicesMap<MXKey>> {
|
internal interface ClaimOneTimeKeysForUsersDeviceTask : Task<ClaimOneTimeKeysForUsersDeviceTask.Params, MXUsersDevicesMap<MXKey>> {
|
||||||
@ -45,31 +44,25 @@ internal class DefaultClaimOneTimeKeysForUsersDevice @Inject constructor(private
|
|||||||
apiCall = cryptoApi.claimOneTimeKeysForUsersDevices(body)
|
apiCall = cryptoApi.claimOneTimeKeysForUsersDevices(body)
|
||||||
}.flatMap { keysClaimResponse ->
|
}.flatMap { keysClaimResponse ->
|
||||||
Try {
|
Try {
|
||||||
val map = HashMap<String, Map<String, MXKey>>()
|
val map = MXUsersDevicesMap<MXKey>()
|
||||||
|
|
||||||
if (null != keysClaimResponse.oneTimeKeys) {
|
if (null != keysClaimResponse.oneTimeKeys) {
|
||||||
for (userId in keysClaimResponse.oneTimeKeys!!.keys) {
|
for (userId in keysClaimResponse.oneTimeKeys!!.keys) {
|
||||||
val mapByUserId = keysClaimResponse.oneTimeKeys!![userId]
|
val mapByUserId = keysClaimResponse.oneTimeKeys!![userId]
|
||||||
|
|
||||||
val keysMap = HashMap<String, MXKey>()
|
|
||||||
|
|
||||||
for (deviceId in mapByUserId!!.keys) {
|
for (deviceId in mapByUserId!!.keys) {
|
||||||
val mxKey = MXKey.from(mapByUserId[deviceId])
|
val mxKey = MXKey.from(mapByUserId[deviceId])
|
||||||
|
|
||||||
if (mxKey != null) {
|
if (mxKey != null) {
|
||||||
keysMap[deviceId] = mxKey
|
map.setObject(userId, deviceId, mxKey)
|
||||||
} else {
|
} else {
|
||||||
Timber.e("## claimOneTimeKeysForUsersDevices : fail to create a MXKey")
|
Timber.e("## claimOneTimeKeysForUsersDevices : fail to create a MXKey")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keysMap.size != 0) {
|
|
||||||
map[userId] = keysMap
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MXUsersDevicesMap(map)
|
map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -223,7 +223,7 @@ internal class DefaultSasVerificationService @Inject constructor(private val cre
|
|||||||
.fold(
|
.fold(
|
||||||
{ error() },
|
{ error() },
|
||||||
{
|
{
|
||||||
if (it.getUserDeviceIds(otherUserId).contains(startReq.fromDevice)) {
|
if (it.getUserDeviceIds(otherUserId)?.contains(startReq.fromDevice) == true) {
|
||||||
success(it)
|
success(it)
|
||||||
} else {
|
} else {
|
||||||
error()
|
error()
|
||||||
@ -410,7 +410,7 @@ internal class DefaultSasVerificationService @Inject constructor(private val cre
|
|||||||
fun cancelTransaction(transactionId: String, userId: String, userDevice: String, code: CancelCode) {
|
fun cancelTransaction(transactionId: String, userId: String, userDevice: String, code: CancelCode) {
|
||||||
val cancelMessage = KeyVerificationCancel.create(transactionId, code)
|
val cancelMessage = KeyVerificationCancel.create(transactionId, code)
|
||||||
val contentMap = MXUsersDevicesMap<Any>()
|
val contentMap = MXUsersDevicesMap<Any>()
|
||||||
contentMap.setObject(cancelMessage, userId, userDevice)
|
contentMap.setObject(userId, userDevice, cancelMessage)
|
||||||
|
|
||||||
sendToDeviceTask.configureWith(SendToDeviceTask.Params(EventType.KEY_VERIFICATION_CANCEL, contentMap, transactionId))
|
sendToDeviceTask.configureWith(SendToDeviceTask.Params(EventType.KEY_VERIFICATION_CANCEL, contentMap, transactionId))
|
||||||
.dispatchTo(object : MatrixCallback<Unit> {
|
.dispatchTo(object : MatrixCallback<Unit> {
|
||||||
|
@ -21,12 +21,11 @@ import im.vector.matrix.android.api.session.crypto.sas.OutgoingSasVerificationRe
|
|||||||
import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTxState
|
import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTxState
|
||||||
import im.vector.matrix.android.api.session.events.model.EventType
|
import im.vector.matrix.android.api.session.events.model.EventType
|
||||||
import im.vector.matrix.android.internal.crypto.actions.SetDeviceVerificationAction
|
import im.vector.matrix.android.internal.crypto.actions.SetDeviceVerificationAction
|
||||||
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
|
||||||
import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
|
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.KeyVerificationAccept
|
import im.vector.matrix.android.internal.crypto.model.rest.KeyVerificationAccept
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.KeyVerificationKey
|
import im.vector.matrix.android.internal.crypto.model.rest.KeyVerificationKey
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.KeyVerificationMac
|
import im.vector.matrix.android.internal.crypto.model.rest.KeyVerificationMac
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.KeyVerificationStart
|
import im.vector.matrix.android.internal.crypto.model.rest.KeyVerificationStart
|
||||||
|
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
||||||
import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask
|
import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask
|
||||||
import im.vector.matrix.android.internal.di.MoshiProvider
|
import im.vector.matrix.android.internal.di.MoshiProvider
|
||||||
import im.vector.matrix.android.internal.task.TaskExecutor
|
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||||
@ -102,8 +101,6 @@ internal class OutgoingSASVerificationRequest(
|
|||||||
startMessage.shortAuthenticationStrings = KNOWN_SHORT_CODES
|
startMessage.shortAuthenticationStrings = KNOWN_SHORT_CODES
|
||||||
|
|
||||||
startReq = startMessage
|
startReq = startMessage
|
||||||
val contentMap = MXUsersDevicesMap<Any>()
|
|
||||||
contentMap.setObject(startMessage, otherUserId, otherDeviceId)
|
|
||||||
state = SasVerificationTxState.SendingStart
|
state = SasVerificationTxState.SendingStart
|
||||||
|
|
||||||
sendToOther(
|
sendToOther(
|
||||||
|
@ -285,7 +285,7 @@ internal abstract class SASVerificationTransaction(
|
|||||||
onErrorReason: CancelCode,
|
onErrorReason: CancelCode,
|
||||||
onDone: (() -> Unit)?) {
|
onDone: (() -> Unit)?) {
|
||||||
val contentMap = MXUsersDevicesMap<Any>()
|
val contentMap = MXUsersDevicesMap<Any>()
|
||||||
contentMap.setObject(keyToDevice, otherUserId, otherDeviceId)
|
contentMap.setObject(otherUserId, otherDeviceId, keyToDevice)
|
||||||
|
|
||||||
sendToDeviceTask.configureWith(SendToDeviceTask.Params(type, contentMap, transactionId))
|
sendToDeviceTask.configureWith(SendToDeviceTask.Params(type, contentMap, transactionId))
|
||||||
.dispatchTo(object : MatrixCallback<Unit> {
|
.dispatchTo(object : MatrixCallback<Unit> {
|
||||||
|
@ -94,7 +94,7 @@ class KeyRequestHandler @Inject constructor(val context: Context,
|
|||||||
//Add a notification for every incoming request
|
//Add a notification for every incoming request
|
||||||
session.downloadKeys(Arrays.asList(userId), false, object : MatrixCallback<MXUsersDevicesMap<MXDeviceInfo>> {
|
session.downloadKeys(Arrays.asList(userId), false, object : MatrixCallback<MXUsersDevicesMap<MXDeviceInfo>> {
|
||||||
override fun onSuccess(data: MXUsersDevicesMap<MXDeviceInfo>) {
|
override fun onSuccess(data: MXUsersDevicesMap<MXDeviceInfo>) {
|
||||||
val deviceInfo = data.getObject(deviceId, userId)
|
val deviceInfo = data.getObject(userId, deviceId)
|
||||||
|
|
||||||
if (null == deviceInfo) {
|
if (null == deviceInfo) {
|
||||||
Timber.e("## displayKeyShareDialog() : No details found for device $userId:$deviceId")
|
Timber.e("## displayKeyShareDialog() : No details found for device $userId:$deviceId")
|
||||||
|
Loading…
Reference in New Issue
Block a user