make gotr plugin visible but not activatable if potr is missing

This commit is contained in:
Yann Leboulanger
2012-05-01 00:48:26 +02:00
parent 8bff21d54b
commit e8f0870878
2 changed files with 136 additions and 129 deletions

View File

@@ -74,148 +74,147 @@ try:
import potr
if not hasattr(potr, 'VERSION') or potr.VERSION < MINVERSION:
raise ImportError('old / unsupported python-otr version')
except ImportError:
HAS_POTR = False
def get_jid_from_fjid(fjid):
return gajim.get_room_and_nick_from_fjid(fjid)[0]
def get_jid_from_fjid(fjid):
return gajim.get_room_and_nick_from_fjid(fjid)[0]
class GajimContext(potr.context.Context):
# self.peer is fjid
# self.jid does not contain resource
__slots__ = ['smpWindow', 'jid']
class GajimContext(potr.context.Context):
# self.peer is fjid
# self.jid does not contain resource
__slots__ = ['smpWindow', 'jid']
def __init__(self, account, peer):
super(GajimContext, self).__init__(account, peer)
self.jid = get_jid_from_fjid(peer)
self.trustName = self.jid
self.smpWindow = ui.ContactOtrSmpWindow(self)
def __init__(self, account, peer):
super(GajimContext, self).__init__(account, peer)
self.jid = get_jid_from_fjid(peer)
self.trustName = self.jid
self.smpWindow = ui.ContactOtrSmpWindow(self)
def inject(self, msg, appdata=None):
log.debug('inject(appdata=%s)', appdata)
msg = unicode(msg)
account = self.user.accountname
def inject(self, msg, appdata=None):
log.debug('inject(appdata=%s)', appdata)
msg = unicode(msg)
account = self.user.accountname
stanza = common.xmpp.Message(to=self.peer, body=msg, typ='chat')
if appdata is not None:
session = appdata.get('session', None)
if session is not None:
stanza.setThread(session.thread_id)
gajim.connections[account].connection.send(stanza, now=True)
stanza = common.xmpp.Message(to=self.peer, body=msg, typ='chat')
if appdata is not None:
session = appdata.get('session', None)
if session is not None:
stanza.setThread(session.thread_id)
gajim.connections[account].connection.send(stanza, now=True)
def setState(self, newstate):
if self.state == potr.context.STATE_ENCRYPTED:
# we were encrypted
if newstate == potr.context.STATE_ENCRYPTED:
# and are still -> it's just a refresh
OtrPlugin.gajim_log(
_('Private conversation with %s refreshed.') % self.peer,
self.user.accountname, self.peer)
elif newstate == potr.context.STATE_FINISHED:
# and aren't anymore -> other side disconnected
OtrPlugin.gajim_log(_('%s has ended his/her private '
'conversation with you. You should do the same.')
% self.peer, self.user.accountname, self.peer)
else:
if newstate == potr.context.STATE_ENCRYPTED:
# we are now encrypted
trust = self.getCurrentTrust()
if trust is None:
fpr = str(self.getCurrentKey())
OtrPlugin.gajim_log(_('New fingerprint for %(peer)s: %(fpr)s')
% {'peer': self.peer, 'fpr': fpr},
def setState(self, newstate):
if self.state == potr.context.STATE_ENCRYPTED:
# we were encrypted
if newstate == potr.context.STATE_ENCRYPTED:
# and are still -> it's just a refresh
OtrPlugin.gajim_log(
_('Private conversation with %s refreshed.') % self.peer,
self.user.accountname, self.peer)
self.setCurrentTrust('')
trustStr = 'authenticated' if bool(trust) else '*unauthenticated*'
elif newstate == potr.context.STATE_FINISHED:
# and aren't anymore -> other side disconnected
OtrPlugin.gajim_log(_('%s has ended his/her private '
'conversation with you. You should do the same.')
% self.peer, self.user.accountname, self.peer)
else:
if newstate == potr.context.STATE_ENCRYPTED:
# we are now encrypted
trust = self.getCurrentTrust()
if trust is None:
fpr = str(self.getCurrentKey())
OtrPlugin.gajim_log(_('New fingerprint for %(peer)s: %(fpr)s')
% {'peer': self.peer, 'fpr': fpr},
self.user.accountname, self.peer)
self.setCurrentTrust('')
trustStr = 'authenticated' if bool(trust) else '*unauthenticated*'
OtrPlugin.gajim_log(
_('%(trustStr)s secured OTR conversation with %(peer)s started')
% {'trustStr': trustStr, 'peer': self.peer},
self.user.accountname, self.peer)
if self.state != potr.context.STATE_PLAINTEXT and \
newstate == potr.context.STATE_PLAINTEXT:
# we are now plaintext
OtrPlugin.gajim_log(
_('%(trustStr)s secured OTR conversation with %(peer)s started')
% {'trustStr': trustStr, 'peer': self.peer},
self.user.accountname, self.peer)
_('Private conversation with %s lost.') % self.peer,
self.user.accountname, self.peer)
if self.state != potr.context.STATE_PLAINTEXT and \
newstate == potr.context.STATE_PLAINTEXT:
# we are now plaintext
OtrPlugin.gajim_log(
_('Private conversation with %s lost.') % self.peer,
self.user.accountname, self.peer)
super(GajimContext, self).setState(newstate)
OtrPlugin.update_otr(self.peer, self.user.accountname)
self.user.plugin.update_context_list()
super(GajimContext, self).setState(newstate)
OtrPlugin.update_otr(self.peer, self.user.accountname)
self.user.plugin.update_context_list()
def getPolicy(self, key):
ret = self.user.plugin.get_flags(self.user.accountname, self.jid)[key]
log.debug('getPolicy(key=%s) = %s', key, ret)
return ret
def getPolicy(self, key):
ret = self.user.plugin.get_flags(self.user.accountname, self.jid)[key]
log.debug('getPolicy(key=%s) = %s', key, ret)
return ret
class GajimOtrAccount(potr.context.Account):
contextclass = GajimContext
def __init__(self, plugin, accountname):
global PROTOCOL, MMS
self.plugin = plugin
self.accountname = accountname
name = gajim.get_jid_from_account(accountname)
super(GajimOtrAccount, self).__init__(name, PROTOCOL, MMS)
self.keyFilePath = os.path.join(gajim.gajimpaths.data_root, accountname)
class GajimOtrAccount(potr.context.Account):
contextclass = GajimContext
def __init__(self, plugin, accountname):
global PROTOCOL, MMS
self.plugin = plugin
self.accountname = accountname
name = gajim.get_jid_from_account(accountname)
super(GajimOtrAccount, self).__init__(name, PROTOCOL, MMS)
self.keyFilePath = os.path.join(gajim.gajimpaths.data_root, accountname)
def dropPrivkey(self):
try:
os.remove(self.keyFilePath + '.key3')
except IOError, e:
if e.errno != 2:
log.exception('IOError occurred when removing key file for %s',
self.name)
self.privkey = None
def dropPrivkey(self):
try:
os.remove(self.keyFilePath + '.key3')
except IOError, e:
if e.errno != 2:
log.exception('IOError occurred when removing key file for %s',
self.name)
self.privkey = None
def loadPrivkey(self):
try:
with open(self.keyFilePath + '.key3', 'rb') as keyFile:
return potr.crypt.PK.parsePrivateKey(keyFile.read())[0]
except IOError, e:
if e.errno != 2:
log.exception('IOError occurred when loading key file for %s',
self.name)
return None
def loadPrivkey(self):
try:
with open(self.keyFilePath + '.key3', 'rb') as keyFile:
return potr.crypt.PK.parsePrivateKey(keyFile.read())[0]
except IOError, e:
if e.errno != 2:
def savePrivkey(self):
try:
with open(self.keyFilePath + '.key3', 'wb') as keyFile:
keyFile.write(self.getPrivkey().serializePrivateKey())
except IOError, e:
log.exception('IOError occurred when loading key file for %s',
self.name)
return None
def savePrivkey(self):
try:
with open(self.keyFilePath + '.key3', 'wb') as keyFile:
keyFile.write(self.getPrivkey().serializePrivateKey())
except IOError, e:
log.exception('IOError occurred when loading key file for %s',
self.name)
def loadTrusts(self, newCtxCb=None):
''' load the fingerprint trustdb '''
# it has the same format as libotr, therefore the
# redundant account / proto field
try:
with open(self.keyFilePath + '.fpr', 'r') as fprFile:
for line in fprFile:
ctx, acc, proto, fpr, trust = line[:-1].split('\t')
def loadTrusts(self, newCtxCb=None):
''' load the fingerprint trustdb '''
# it has the same format as libotr, therefore the
# redundant account / proto field
try:
with open(self.keyFilePath + '.fpr', 'r') as fprFile:
for line in fprFile:
ctx, acc, proto, fpr, trust = line[:-1].split('\t')
if acc != self.name or proto != PROTOCOL:
continue
if acc != self.name or proto != PROTOCOL:
continue
jid = get_jid_from_fjid(ctx)
self.setTrust(jid, fpr, trust)
except IOError, e:
if e.errno != 2:
log.exception('IOError occurred when loading fpr file for %s',
self.name)
jid = get_jid_from_fjid(ctx)
self.setTrust(jid, fpr, trust)
except IOError, e:
if e.errno != 2:
def saveTrusts(self):
try:
with open(self.keyFilePath + '.fpr', 'w') as fprFile:
for uid, trusts in self.trusts.iteritems():
for fpr, trustVal in trusts.iteritems():
fprFile.write('\t'.join(
(uid, self.name, PROTOCOL, fpr, trustVal)))
fprFile.write('\n')
except IOError, e:
log.exception('IOError occurred when loading fpr file for %s',
self.name)
def saveTrusts(self):
try:
with open(self.keyFilePath + '.fpr', 'w') as fprFile:
for uid, trusts in self.trusts.iteritems():
for fpr, trustVal in trusts.iteritems():
fprFile.write('\t'.join(
(uid, self.name, PROTOCOL, fpr, trustVal)))
fprFile.write('\n')
except IOError, e:
log.exception('IOError occurred when loading fpr file for %s',
self.name)
except ImportError:
HAS_POTR = False
def otr_dialog_destroy(widget, *args, **kwargs):
widget.destroy()
@@ -236,15 +235,19 @@ class OtrPlugin(GajimPlugin):
self.gui_extension_points = {
'chat_control' : (self.cc_connect, self.cc_disconnect)
}
if not HAS_POTR:
self.activatable = False
self.available_text = 'potr is not installed. Get it from %s' % \
'https://github.com/afflux/pure-python-otr'
else:
for acc in gajim.contacts.get_accounts():
self.us[acc] = GajimOtrAccount(self, acc)
self.us[acc].loadTrusts()
for acc in gajim.contacts.get_accounts():
self.us[acc] = GajimOtrAccount(self, acc)
self.us[acc].loadTrusts()
acc = str(acc)
if acc not in self.config or None not in self.config[acc]:
self.config[acc] = {None:DEFAULTFLAGS.copy()}
self.update_context_list()
acc = str(acc)
if acc not in self.config or None not in self.config[acc]:
self.config[acc] = {None:DEFAULTFLAGS.copy()}
self.update_context_list()
@log_calls('OtrPlugin')
def activate(self):

View File

@@ -24,7 +24,11 @@ from common import gajim
from plugins.gui import GajimPluginConfigDialog
import otrmodule
import potr
HAS_PORT = True
try:
import potr
except:
HAS_POTR = False
class OtrPluginConfigDialog(GajimPluginConfigDialog):