Skip to content
Snippets Groups Projects
Commit 1dca6604 authored by Philipp Hörist's avatar Philipp Hörist
Browse files

Handle session states (inactive/active) (#68)

* Add DB migration to insert 'active' column

Inserts 'active' column into the sessions table with
a Default value of 1

* Set active/inactiv state of sessions

Every device that we receive via devicelist event will be set
to 'active', every device in our DB that is not in the received
devicelist event will be set to 'inactive'

* Show inactive session fingerprints in grey color
parent cc56bad8
No related branches found
No related tags found
No related merge requests found
......@@ -265,6 +265,7 @@ class OmemoPlugin(GajimPlugin):
log.info(account_name + ' => Received own device list:' + str(
devices_list))
state.set_own_devices(devices_list)
state.store.sessionStore.setActiveState(devices_list, my_jid)
if not state.own_device_id_published() or anydup(
state.own_devices):
......@@ -278,6 +279,7 @@ class OmemoPlugin(GajimPlugin):
log.info(account_name + ' => Received device list for ' +
contact_jid + ':' + str(devices_list))
state.set_devices(contact_jid, devices_list)
state.store.sessionStore.setActiveState(devices_list, contact_jid)
if (account_name in self.ui_list and
contact_jid not in self.ui_list[account_name]):
......@@ -517,6 +519,8 @@ class OmemoPlugin(GajimPlugin):
contact_jid = stanza.getAttr('from')
if contact_jid == my_jid:
state.set_own_devices(devices_list)
state.store.sessionStore.setActiveState(devices_list, my_jid)
if not state.own_device_id_published() or anydup(
state.own_devices):
# Our own device_id is not in the list, it could be
......
......@@ -121,4 +121,16 @@ def migrate(dbConn):
END TRANSACTION;
""" % (add_index))
if user_version(dbConn) < 4:
# Adds column "active" to the sessions table
add_active = """ ALTER TABLE sessions
ADD COLUMN active INTEGER DEFAULT 1;
"""
dbConn.executescript(""" BEGIN TRANSACTION;
%s
PRAGMA user_version=4;
END TRANSACTION;
""" % (add_active))
return dbConn
......@@ -94,8 +94,8 @@ class LiteAxolotlStore(AxolotlStore):
def loadSession(self, recepientId, deviceId):
return self.sessionStore.loadSession(recepientId, deviceId)
def getDeviceTuples(self):
return self.sessionStore.getDeviceTuples()
def getActiveDeviceTuples(self):
return self.sessionStore.getActiveDeviceTuples()
def getSubDeviceSessions(self, recepientId):
# TODO Reuse this
......
......@@ -53,13 +53,13 @@ class LiteSessionStore(SessionStore):
deviceIds = [r[0] for r in result]
return deviceIds
def getDeviceTuples(self):
q = "SELECT recipient_id, device_id from sessions"
c = self.dbConn.cursor()
result = []
for row in c.execute(q):
result.append((row[0],row[1]))
return result
def getActiveDeviceTuples(self):
q = "SELECT recipient_id, device_id FROM sessions WHERE active = 1"
c = self.dbConn.cursor()
result = []
for row in c.execute(q):
result.append((row[0], row[1]))
return result
def storeSession(self, recipientId, deviceId, sessionRecord):
self.deleteSession(recipientId, deviceId)
......@@ -86,3 +86,39 @@ class LiteSessionStore(SessionStore):
q = "DELETE FROM sessions WHERE recipient_id = ?"
self.dbConn.cursor().execute(q, (recipientId, ))
self.dbConn.commit()
def setActiveState(self, deviceList, jid):
c = self.dbConn.cursor()
q = "UPDATE sessions SET active = {} " \
"WHERE recipient_id = '{}' AND device_id IN ({})" \
.format(1, jid, ', '.join(['?'] * len(deviceList)))
c.execute(q, deviceList)
q = "UPDATE sessions SET active = {} " \
"WHERE recipient_id = '{}' AND device_id NOT IN ({})" \
.format(0, jid, ', '.join(['?'] * len(deviceList)))
c.execute(q, deviceList)
self.dbConn.commit()
def getActiveSessionsKeys(self, recipientId):
q = "SELECT record FROM sessions WHERE active = 1 AND recipient_id = ?"
c = self.dbConn.cursor()
result = []
for row in c.execute(q, (recipientId,)):
public_key = (SessionRecord(serialized=row[0]).
getSessionState().getRemoteIdentityKey().
getPublicKey())
result.append(public_key.serialize())
return result
def getAllActiveSessionsKeys(self):
q = "SELECT record FROM sessions WHERE active = 1"
c = self.dbConn.cursor()
result = []
for row in c.execute(q):
public_key = (SessionRecord(serialized=row[0]).
getSessionState().getRemoteIdentityKey().
getPublicKey())
result.append(public_key.serialize())
return result
......@@ -59,7 +59,7 @@ class OmemoState:
self.own_devices = []
self.store = LiteAxolotlStore(connection)
self.encryption = self.store.encryptionStore
for jid, device_id in self.store.getDeviceTuples():
for jid, device_id in self.store.getActiveDeviceTuples():
if jid != own_jid:
self.add_device(jid, device_id)
else:
......
......@@ -284,19 +284,37 @@ class OMEMOConfigDialog(GajimPluginConfigDialog):
% ownfpr)
fprDB = state.store.identityKeyStore.getAllFingerprints()
activeSessions = state.store.sessionStore. \
getAllActiveSessionsKeys()
for item in fprDB:
_id, jid, fpr, tr = item
if fpr in activeSessions:
active = True
else:
active = False
fpr = binascii.hexlify(fpr)
fpr = self.human_hash(fpr[2:])
if tr == UNTRUSTED:
self.fpr_model.append((_id, jid, 'False',
'<tt><span foreground="#FF0040">%s</span></tt>' % fpr))
if active:
self.fpr_model.append((_id, jid, 'False',
'<tt><span foreground="#FF0040">%s</span></tt>' % fpr))
else:
self.fpr_model.append((_id, jid, 'False',
'<tt><span foreground="#585858">%s</span></tt>' % fpr))
elif tr == TRUSTED:
self.fpr_model.append((_id, jid, 'True',
'<tt><span foreground="#2EFE2E">%s</span></tt>' % fpr))
if active:
self.fpr_model.append((_id, jid, 'True',
'<tt><span foreground="#2EFE2E">%s</span></tt>' % fpr))
else:
self.fpr_model.append((_id, jid, 'True',
'<tt><span foreground="#585858">%s</span></tt>' % fpr))
else:
self.fpr_model.append((_id, jid, 'Undecided',
'<tt><span foreground="#FF8000">%s</span></tt>' % fpr))
if active:
self.fpr_model.append((_id, jid, 'Undecided',
'<tt><span foreground="#FF8000">%s</span></tt>' % fpr))
else:
self.fpr_model.append((_id, jid, 'Undecided',
'<tt><span foreground="#585858">%s</span></tt>' % fpr))
for item in state.own_devices:
self.device_model.append([item])
......@@ -419,20 +437,38 @@ class FingerprintWindow(gtk.Dialog):
% ownfpr)
fprDB = state.store.identityKeyStore.getFingerprints(self.contact.jid)
activeSessions = state.store.sessionStore. \
getActiveSessionsKeys(self.contact.jid)
for item in fprDB:
_id, jid, fpr, tr = item
if fpr in activeSessions:
active = True
else:
active = False
fpr = binascii.hexlify(fpr)
fpr = self.human_hash(fpr[2:])
if tr == UNTRUSTED:
self.fpr_model.append((_id, jid, 'False',
'<tt><span foreground="#FF0040">%s</span></tt>' % fpr))
if active:
self.fpr_model.append((_id, jid, 'False',
'<tt><span foreground="#FF0040">%s</span></tt>' % fpr))
else:
self.fpr_model.append((_id, jid, 'False',
'<tt><span foreground="#585858">%s</span></tt>' % fpr))
elif tr == TRUSTED:
self.fpr_model.append((_id, jid, 'True',
'<tt><span foreground="#2EFE2E">%s</span></tt>' % fpr))
if active:
self.fpr_model.append((_id, jid, 'True',
'<tt><span foreground="#2EFE2E">%s</span></tt>' % fpr))
else:
self.fpr_model.append((_id, jid, 'True',
'<tt><span foreground="#585858">%s</span></tt>' % fpr))
else:
self.fpr_model.append((_id, jid, 'Undecided',
'<tt><span foreground="#FF8000">%s</span></tt>' % fpr))
if active:
self.fpr_model.append((_id, jid, 'Undecided',
'<tt><span foreground="#FF8000">%s</span></tt>' % fpr))
else:
self.fpr_model.append((_id, jid, 'Undecided',
'<tt><span foreground="#585858">%s</span></tt>' % fpr))
def human_hash(self, fpr):
fpr = fpr.upper()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment