1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-12-01 04:43:29 +03:00

Merge pull request #178 from matrix-org/rav/refactor_ensuresessions

Change the result structure for ensureOlmSessionsForUsers
This commit is contained in:
Richard van der Hoff
2016-08-23 11:19:19 +01:00
committed by GitHub
3 changed files with 75 additions and 41 deletions

View File

@@ -94,6 +94,15 @@ DeviceInfo.prototype.getFingerprint = function() {
return this.keys["ed25519:" + this.deviceId]; return this.keys["ed25519:" + this.deviceId];
}; };
/**
* Get the identity key for this device (ie, the Curve25519 key)
*
* @return {string} base64-encoded identity key of this device
*/
DeviceInfo.prototype.getIdentityKey = function() {
return this.keys["curve25519:" + this.deviceId];
};
/** /**
* Get the configured display name for this device, if any * Get the configured display name for this device, if any
* *

View File

@@ -546,56 +546,81 @@ Crypto.prototype.setRoomEncryption = function(roomId, config, roomMembers) {
return alg.initRoomEncryption(roomMembers); return alg.initRoomEncryption(roomMembers);
}; };
/**
* @typedef {Object} module:crypto~OlmSessionResult
* @property {module:crypto-deviceinfo} device device info
* @property {string?} sessionId base64 olm session id; null if no session
* could be established
*/
/** /**
* Try to make sure we have established olm sessions for the given users. * Try to make sure we have established olm sessions for the given users.
* *
* @param {string[]} users list of user ids * @param {string[]} users list of user ids
* *
* @return {module:client.Promise} resolves once the sessions are complete, to * @return {module:client.Promise} resolves once the sessions are complete, to
* an object with keys <tt>missingUsers</tt> (a list of users with no known * an Object mapping from userId to deviceId to
* olm devices), and <tt>missingDevices</tt> a list of olm devices with no * {@link module:crypto~OlmSessionResult}
* known one-time keys.
*/ */
Crypto.prototype.ensureOlmSessionsForUsers = function(users) { Crypto.prototype.ensureOlmSessionsForUsers = function(users) {
var devicesWithoutSession = []; var devicesWithoutSession = [
var userWithoutDevices = []; // [userId, deviceId, deviceInfo], ...
];
var result = {};
for (var i = 0; i < users.length; ++i) { for (var i = 0; i < users.length; ++i) {
var userId = users[i]; var userId = users[i];
var devices = this._sessionStore.getEndToEndDevicesForUser(userId); result[userId] = {};
if (!devices) {
userWithoutDevices.push(userId); var devices = this.getStoredDevicesForUser(userId);
} else { for (var j = 0; j < devices.length; ++j) {
for (var deviceId in devices) { var deviceInfo = devices[j];
if (devices.hasOwnProperty(deviceId)) { var deviceId = deviceInfo.deviceId;
var keys = devices[deviceId];
var key = keys.keys["curve25519:" + deviceId]; var key = deviceInfo.getIdentityKey();
if (key == this._olmDevice.deviceCurve25519Key) { if (key == this._olmDevice.deviceCurve25519Key) {
continue; // don't bother setting up session to ourself
} continue;
if (!this._sessionStore.getEndToEndSessions(key)) {
devicesWithoutSession.push([userId, deviceId, key]);
}
}
} }
if (deviceInfo.verified == DeviceVerification.BLOCKED) {
// don't bother setting up sessions with blocked users
continue;
}
var sessionId = this._olmDevice.getSessionIdForDevice(key);
if (sessionId === null) {
devicesWithoutSession.push([userId, deviceId, deviceInfo]);
}
result[userId][deviceId] = {
device: deviceInfo,
sessionId: sessionId,
};
} }
} }
if (devicesWithoutSession.length === 0) { if (devicesWithoutSession.length === 0) {
return q({ return q(result);
missingUsers: userWithoutDevices,
missingDevices: []
});
} }
// TODO: this has a race condition - if we try to send another message
// while we are claiming a key, we will end up claiming two and setting up
// two sessions.
//
// That should eventually resolve itself, but it's poor form.
var self = this; var self = this;
return this._baseApis.claimOneTimeKeys( return this._baseApis.claimOneTimeKeys(
devicesWithoutSession devicesWithoutSession
).then(function(res) { ).then(function(res) {
var missing = {}; for (var i = 0; i < devicesWithoutSession.length; ++i) {
for (i = 0; i < devicesWithoutSession.length; ++i) {
var device = devicesWithoutSession[i]; var device = devicesWithoutSession[i];
var userRes = res.one_time_keys[device[0]] || {}; var userId = device[0];
var deviceRes = userRes[device[1]]; var deviceId = device[1];
var deviceInfo = device[2];
var userRes = res.one_time_keys[userId] || {};
var deviceRes = userRes[deviceId];
var oneTimeKey; var oneTimeKey;
for (var keyId in deviceRes) { for (var keyId in deviceRes) {
if (keyId.indexOf("curve25519:") === 0) { if (keyId.indexOf("curve25519:") === 0) {
@@ -604,20 +629,18 @@ Crypto.prototype.ensureOlmSessionsForUsers = function(users) {
} }
if (oneTimeKey) { if (oneTimeKey) {
var sid = self._olmDevice.createOutboundSession( var sid = self._olmDevice.createOutboundSession(
device[2], oneTimeKey deviceInfo.getIdentityKey(), oneTimeKey
); );
console.log("Started new sessionid " + sid + console.log("Started new sessionid " + sid +
" for device " + device[2]); " for device " + userId + ":" + deviceId);
result[userId][deviceId].sessionId = sid;
} else { } else {
missing[device[0]] = missing[device[0]] || []; console.warn("No one-time keys for device " +
missing[device[0]].push([device[1]]); userId + ":" + deviceId);
} }
} }
return result;
return {
missingUsers: userWithoutDevices,
missingDevices: missing
};
}); });
}; };

View File

@@ -213,8 +213,9 @@ function aliEnablesEncryption() {
var p = aliClient.setRoomEncryption(roomId, { var p = aliClient.setRoomEncryption(roomId, {
algorithm: "m.olm.v1.curve25519-aes-sha2", algorithm: "m.olm.v1.curve25519-aes-sha2",
}).then(function(res) { }).then(function(res) {
expect(res.missingUsers).toEqual([]); expect(res[aliUserId]).toEqual({});
expect(res.missingDevices).toEqual({}); expect(res[bobUserId][bobDeviceId].device).toBeDefined();
expect(res[bobUserId][bobDeviceId].sessionId).toBeDefined();
expect(aliClient.isRoomEncrypted(roomId)).toBeTruthy(); expect(aliClient.isRoomEncrypted(roomId)).toBeTruthy();
}); });
aliHttpBackend.flush(); aliHttpBackend.flush();
@@ -226,8 +227,9 @@ function bobEnablesEncryption() {
return bobClient.setRoomEncryption(roomId, { return bobClient.setRoomEncryption(roomId, {
algorithm: "m.olm.v1.curve25519-aes-sha2", algorithm: "m.olm.v1.curve25519-aes-sha2",
}).then(function(res) { }).then(function(res) {
expect(res.missingUsers).toEqual([]); expect(res[aliUserId][aliDeviceId].device).toBeDefined();
expect(res.missingDevices).toEqual({}); expect(res[aliUserId][aliDeviceId].sessionId).toBeDefined();
expect(res[bobUserId]).toEqual({});
expect(bobClient.isRoomEncrypted(roomId)).toBeTruthy(); expect(bobClient.isRoomEncrypted(roomId)).toBeTruthy();
}); });
} }