comparison src/browser/sat_browser/plugin_sec_otr.py @ 538:3317e5d0ac1d

browser_side (plugin OTR): put all the text messages into constants
author souliane <souliane@mailoo.org>
date Sun, 07 Sep 2014 22:33:28 +0200
parents cd492c18b366
children 19b8af73e945
comparison
equal deleted inserted replaced
537:cd492c18b366 538:3317e5d0ac1d
35 35
36 NS_OTR = "otr_plugin" 36 NS_OTR = "otr_plugin"
37 PRIVATE_KEY = "PRIVATE KEY" 37 PRIVATE_KEY = "PRIVATE KEY"
38 MAIN_MENU = D_('OTR encryption') 38 MAIN_MENU = D_('OTR encryption')
39 DIALOG_EOL = "<br />" 39 DIALOG_EOL = "<br />"
40 AUTH_INFO_TXT = D_("Authenticating a correspondent helps ensure that the person you are talking to is who he or she claims to be.{eol}{eol}").format(eol=DIALOG_EOL) 40
41 AUTH_FINGERPRINT_TXT = D_("<i>To verify the fingerprint, contact your correspondent via some other authenticated channel (i.e. not in this chat), such as the telephone or GPG-signed email. Each of you should tell your fingerprint to the other.</i>{eol}{eol}").format(eol=DIALOG_EOL) 41 AUTH_TRUSTED = D_("Verified")
42 AUTH_QUEST_DEF = D_("<i>To authenticate using a question, pick a question whose answer is known only to you and your correspondent. Enter this question and this answer, then wait for your correspondent to enter the answer too. If the answers don't match, then you may be talking to an imposter.</i>{eol}{eol}").format(eol=DIALOG_EOL) 42 AUTH_UNTRUSTED = D_("Unverified")
43 AUTH_QUEST_ASK = D_("<i>Your correspondent is attempting to determine if he or she is really talking to you, or if it's someone pretending to be you. Your correspondent has asked a question, indicated below. To authenticate to your correspondent, enter the answer and click OK.</i>{eol}{eol}").format(eol=DIALOG_EOL) 43 AUTH_OTHER_TITLE = D_("Authentication of {jid}")
44 AUTH_SECRET_TXT = D_("{eol}{eol}Enter secret answer here: (case sensitive){eol}").format(eol=DIALOG_EOL) 44 AUTH_US_TITLE = D_("Authentication to {jid}")
45 FEEDBACK_NOT_PRIVATE = D_("Your conversation with %s is not encrypted.") 45 AUTH_TRUST_NA_TITLE = D_("Authentication requirement")
46 46 AUTH_TRUST_NA_TXT = D_("You must start an OTR conversation before authenticating your correspondent.")
47 DROP_TXT = D_("You private key is used to encrypt messages for your correspondent, nobody except you must know it, if you are in doubt, you should drop it!{eol}{eol}Are you sure you want to drop your private key?").format(eol=DIALOG_EOL) 47 AUTH_INFO_TXT = D_("Authenticating a correspondent helps ensure that the person you are talking to is who he or she claims to be.{eol}{eol}")
48 AUTH_FINGERPRINT_YOURS = D_("Your fingerprint is:{eol}{fingerprint}{eol}{eol}Start an OTR conversation to have your correspondent one.")
49 AUTH_FINGERPRINT_TXT = D_("To verify the fingerprint, contact your correspondent via some other authenticated channel (i.e. not in this chat), such as the telephone or GPG-signed email. Each of you should tell your fingerprint to the other.{eol}{eol}")
50 AUTH_FINGERPRINT_VERIFY = D_("Fingerprint for you, {you}:{eol}{your_fp}{eol}{eol}Purported fingerprint for {other}:{eol}{other_fp}{eol}{eol}Did you verify that this is in fact the correct fingerprint for {other}?")
51 AUTH_QUEST_DEFINE_TXT = D_("To authenticate using a question, pick a question whose answer is known only to you and your correspondent. Enter this question and this answer, then wait for your correspondent to enter the answer too. If the answers don't match, then you may be talking to an imposter.{eol}{eol}")
52 AUTH_QUEST_DEFINE = D_("Enter question here:{eol}")
53 AUTH_QUEST_ANSWER_TXT = D_("Your correspondent is attempting to determine if he or she is really talking to you, or if it's someone pretending to be you. Your correspondent has asked a question, indicated below. To authenticate to your correspondent, enter the answer and click OK.{eol}{eol}")
54 AUTH_QUEST_ANSWER = D_("This is the question asked by your correspondent:{eol}{question}")
55 AUTH_SECRET_INPUT = D_("{eol}{eol}Enter secret answer here: (case sensitive){eol}")
56 AUTH_ABORTED_TXT = D_("Authentication aborted.")
57 AUTH_FAILED_TXT = D_("Authentication failed.")
58 AUTH_OTHER_OK = D_("Authentication successful.")
59 AUTH_US_OK = D_("Your correspondent has successfully authenticated you.")
60 AUTH_OTHER_TOO = D_("You may want to authenticate your correspondent as well by asking your own question.")
61 AUTH_STATUS = D_("The current conversation is now {state}.")
62
63 FINISHED_CONTEXT_TITLE = D_('Finished OTR conversation with {jid}')
64 SEND_PLAIN_IN_FINISHED_CONTEXT = D_("Your message was not sent because your correspondent closed the OTR conversation on his/her side. Either close your own side, or refresh the session.")
65 RECEIVE_PLAIN_IN_ENCRYPTED_CONTEXT = D_("WARNING: received unencrypted data in a supposedly encrypted context!")
66
67 QUERY_ENCRYPTED = D_('Attempting to refresh the OTR conversation with {jid}...')
68 QUERY_NOT_ENCRYPTED = D_('Attempting to start an OTR conversation with {jid}...')
69 AKE_ENCRYPTED = D_(" conversation with {jid} started. Your client is not logging this conversation.")
70 AKE_NOT_ENCRYPTED = D_("ERROR: successfully ake'd with {jid} but the conversation is not encrypted!")
71 END_ENCRYPTED = D_("ERROR: the OTR session ended but the context is still supposedly encrypted!")
72 END_PLAIN = D_("Your conversation with {jid} is no more or hasn't been encrypted.")
73 END_FINISHED = D_("{jid} has ended his or her private conversation with you; you should do the same.")
74
75 KEY_TITLE = D_('Private key')
76 KEY_NA_TITLE = D_("No private key")
77 KEY_NA_TXT = D_("You don't have any private key yet.")
78 KEY_DROP_TITLE = D_('Drop your private key')
79 KEY_DROP_TXT = D_("You private key is used to encrypt messages for your correspondent, nobody except you must know it, if you are in doubt, you should drop it!{eol}{eol}Are you sure you want to drop your private key?")
80 KEY_DROPPED_TXT = D_("Your private key has been dropped.")
81
48 82
49 DEFAULT_POLICY_FLAGS = { 83 DEFAULT_POLICY_FLAGS = {
50 'ALLOW_V2': True, 84 'ALLOW_V2': True,
51 'ALLOW_V3': True, 85 'ALLOW_V3': True,
52 'REQUIRE_ENCRYPTION': False, 86 'REQUIRE_ENCRYPTION': False,
98 log.warning("A plain-text message has been handled by otr.js") 132 log.warning("A plain-text message has been handled by otr.js")
99 log.debug("message received (was %s): %s" % ('encrypted' if encrypted else 'plain', msg)) 133 log.debug("message received (was %s): %s" % ('encrypted' if encrypted else 'plain', msg))
100 if not encrypted: 134 if not encrypted:
101 if self.state == otr.context.STATE_ENCRYPTED: 135 if self.state == otr.context.STATE_ENCRYPTED:
102 log.warning(u"Received unencrypted message in an encrypted context (from %(jid)s)" % {'jid': self.peer.full()}) 136 log.warning(u"Received unencrypted message in an encrypted context (from %(jid)s)" % {'jid': self.peer.full()})
103 feedback = _(u"WARNING: received unencrypted data in a supposedly encrypted context"), 137 self.host.newMessageCb(self.peer, RECEIVE_PLAIN_IN_ENCRYPTED_CONTEXT, C.MESS_TYPE_INFO, self.host.whoami, {})
104 self.host.newMessageCb(self.peer, feedback, C.MESS_TYPE_INFO, self.host.whoami, {})
105 self.host.newMessageCb(self.peer, msg, "chat", self.host.whoami, {}) 138 self.host.newMessageCb(self.peer, msg, "chat", self.host.whoami, {})
106 139
107 def sendMessageCb(self, msg, meta=None): 140 def sendMessageCb(self, msg, meta=None):
108 assert isinstance(self.peer, jid.JID) 141 assert isinstance(self.peer, jid.JID)
109 log.debug("message to send%s: %s" % ((' (attached meta data: %s)' % meta) if meta else '', msg)) 142 log.debug("message to send%s: %s" % ((' (attached meta data: %s)' % meta) if meta else '', msg))
125 other_jid_s = self.peer.full() 158 other_jid_s = self.peer.full()
126 feedback = _(u"Error: the state of the conversation with %s is unknown!") 159 feedback = _(u"Error: the state of the conversation with %s is unknown!")
127 trust = self.getCurrentTrust() 160 trust = self.getCurrentTrust()
128 161
129 if status == otr.context.STATUS_SEND_QUERY: 162 if status == otr.context.STATUS_SEND_QUERY:
130 if msg_state == otr.context.STATE_ENCRYPTED: 163 feedback = QUERY_ENCRYPTED if msg_state == otr.context.STATE_ENCRYPTED else QUERY_NOT_ENCRYPTED
131 feedback = _('Attempting to refresh the private conversation with %s...')
132 else:
133 feedback = _('Attempting to start a private conversation with %s...')
134 164
135 elif status == otr.context.STATUS_AKE_SUCCESS: 165 elif status == otr.context.STATUS_AKE_SUCCESS:
136 trusted_str = _(u"Verified") if trust else _(u"Unverified") 166 trusted_str = AUTH_TRUSTED if trust else AUTH_UNTRUSTED
137 if msg_state == otr.context.STATE_ENCRYPTED: 167 feedback = (trusted_str + AKE_ENCRYPTED) if msg_state == otr.context.STATE_ENCRYPTED else AKE_NOT_ENCRYPTED
138 feedback = trusted_str + (u" conversation with %s started. Your client is not logging this conversation.")
139 else:
140 feedback = _("Error: successfully ake'd with %s but the conversation is not private!")
141 168
142 elif status == otr.context.STATUS_END_OTR: 169 elif status == otr.context.STATUS_END_OTR:
143 if msg_state == otr.context.STATE_PLAINTEXT: 170 if msg_state == otr.context.STATE_PLAINTEXT:
144 feedback = FEEDBACK_NOT_PRIVATE 171 feedback = END_PLAIN
145 elif msg_state == otr.context.STATE_ENCRYPTED: 172 elif msg_state == otr.context.STATE_ENCRYPTED:
146 log.error(_("OTR session ended but the context's state is still 'encrypted'!")) 173 log.error(END_ENCRYPTED)
147 elif msg_state == otr.context.STATE_FINISHED: 174 elif msg_state == otr.context.STATE_FINISHED:
148 feedback = _("%s has ended his/her private conversation with you; you should do the same.") 175 feedback = END_FINISHED
149 176
150 self.host.newMessageCb(self.peer, feedback % other_jid_s, C.MESS_TYPE_INFO, self.host.whoami, {'header_info': Context.getInfoText(msg_state, trust)}) 177 self.host.newMessageCb(self.peer, feedback.format(jid=other_jid_s), C.MESS_TYPE_INFO, self.host.whoami, {'header_info': Context.getInfoText(msg_state, trust)})
151 178
152 def setCurrentTrust(self, new_trust='', act='asked', type_='trust'): 179 def setCurrentTrust(self, new_trust='', act='asked', type_='trust'):
153 log.debug("setCurrentTrust: trust={trust}, act={act}, type={type}".format(type=type_, trust=new_trust, act=act)) 180 log.debug("setCurrentTrust: trust={trust}, act={act}, type={type}".format(type=type_, trust=new_trust, act=act))
154 title = (_("Authentication of {jid}") if act == "asked" else _("Authentication to {jid}")).format(jid=self.peer.full()) 181 title = (AUTH_OTHER_TITLE if act == "asked" else AUTH_US_TITLE).format(jid=self.peer.full())
182 old_trust = self.getCurrentTrust()
155 if type_ == 'abort': 183 if type_ == 'abort':
156 msg = _("Authentication aborted.") 184 msg = AUTH_ABORTED_TXT
157 elif new_trust: 185 elif new_trust:
158 if act == "asked": 186 if act == "asked":
159 msg = _("Authentication successful.") 187 msg = AUTH_OTHER_OK
160 else: 188 else:
161 msg = _("Your correspondent has successfully authenticated you. You may want to authenticate your correspondent as well by asking your own question.") 189 msg = AUTH_US_OK
190 if not old_trust:
191 msg += " " + AUTH_OTHER_TOO
162 else: 192 else:
163 msg = _("Authentication failed.") 193 msg = AUTH_FAILED_TXT
164 dialog.InfoDialog(title, msg, AddStyleName="maxWidthLimit").show() 194 dialog.InfoDialog(title, msg, AddStyleName="maxWidthLimit").show()
165 if act != "asked": 195 if act != "asked":
166 return 196 return
167 old_trust = self.getCurrentTrust()
168 otr.context.Context.setCurrentTrust(self, new_trust) 197 otr.context.Context.setCurrentTrust(self, new_trust)
169 if old_trust != new_trust: 198 if old_trust != new_trust:
170 feedback = _("The privacy status of the current conversation is now: {state}").format(state='Private' if new_trust else 'Unverified') 199 feedback = AUTH_STATUS.format(state=(AUTH_TRUSTED if new_trust else AUTH_UNTRUSTED).lower())
171 self.host.newMessageCb(self.peer, feedback, C.MESS_TYPE_INFO, self.host.whoami, {'header_info': Context.getInfoText(self.state, new_trust)}) 200 self.host.newMessageCb(self.peer, feedback, C.MESS_TYPE_INFO, self.host.whoami, {'header_info': Context.getInfoText(self.state, new_trust)})
172 201
173 def fingerprintAuthCb(self): 202 def fingerprintAuthCb(self):
174 """OTR v2 authentication using manual fingerprint comparison""" 203 """OTR v2 authentication using manual fingerprint comparison"""
175 priv_key = self.user.privkey 204 priv_key = self.user.privkey
179 return 208 return
180 209
181 other_key = self.getCurrentKey() 210 other_key = self.getCurrentKey()
182 if other_key is None: 211 if other_key is None:
183 # we have a private key, but not the fingerprint of our correspondent 212 # we have a private key, but not the fingerprint of our correspondent
184 msg = AUTH_INFO_TXT + ("Your fingerprint is:{eol}{fingerprint}{eol}{eol}Start an OTR conversation to have your correspondent one.").format(fingerprint=priv_key.fingerprint(), eol=DIALOG_EOL) 213 msg = (AUTH_INFO_TXT + AUTH_FINGERPRINT_YOURS).format(fingerprint=priv_key.fingerprint(), eol=DIALOG_EOL)
185 dialog.InfoDialog(_("Fingerprint"), msg, AddStyleName="maxWidthLimit").show() 214 dialog.InfoDialog(_("Fingerprint"), msg, AddStyleName="maxWidthLimit").show()
186 return 215 return
187 216
188 def setTrust(confirm): 217 def setTrust(confirm):
189 self.setCurrentTrust('fingerprint' if confirm else '') 218 self.setCurrentTrust('fingerprint' if confirm else '')
190 219
191 text = AUTH_INFO_TXT + AUTH_FINGERPRINT_TXT + _("Fingerprint for you, {jid}:{eol}{fingerprint}{eol}{eol}").format(jid=self.host.whoami, fingerprint=priv_key.fingerprint(), eol=DIALOG_EOL) 220 text = (AUTH_INFO_TXT + "<i>" + AUTH_FINGERPRINT_TXT + "</i>" + AUTH_FINGERPRINT_VERIFY).format(you=self.host.whoami, your_fp=priv_key.fingerprint(), other=self.peer, other_fp=other_key.fingerprint(), eol=DIALOG_EOL)
192 text += _("Purported fingerprint for {jid}:{eol}{fingerprint}{eol}{eol}").format(jid=self.peer, fingerprint=other_key.fingerprint(), eol=DIALOG_EOL) 221 title = AUTH_OTHER_TITLE.format(jid=self.peer.full())
193 text += _("Did you verify that this is in fact the correct fingerprint for {jid}?").format(jid=self.peer)
194 title = _('Authentication of {jid}').format(jid=self.peer.full())
195 dialog.ConfirmDialog(setTrust, text, title, AddStyleName="maxWidthLimit").show() 222 dialog.ConfirmDialog(setTrust, text, title, AddStyleName="maxWidthLimit").show()
196 223
197 def smpAuthCb(self, type_, data, act=None): 224 def smpAuthCb(self, type_, data, act=None):
198 """OTR v3 authentication using the socialist millionaire protocol. 225 """OTR v3 authentication using the socialist millionaire protocol.
199 226
214 # fingerprints, we will reach this code... that's wrong, this method is for SMP! 241 # fingerprints, we will reach this code... that's wrong, this method is for SMP!
215 # There's probably a bug to fix in otr.js. Do it together with the issue that 242 # There's probably a bug to fix in otr.js. Do it together with the issue that
216 # make us need the dirty self.smpAuthAbort. 243 # make us need the dirty self.smpAuthAbort.
217 else: 244 else:
218 log.error("FIXME: unmanaged ambiguous 'act' value in Context.smpAuthCb!") 245 log.error("FIXME: unmanaged ambiguous 'act' value in Context.smpAuthCb!")
219 title = (_("Authentication of {jid}") if act == "asked" else _("Authentication to {jid}")).format(jid=self.peer.full()) 246 title = (AUTH_OTHER_TITLE if act == "asked" else AUTH_US_TITLE).format(jid=self.peer.full())
220 if type_ == 'question': 247 if type_ == 'question':
221 if act == 'asked': 248 if act == 'asked':
222 def cb(question, answer=None): 249 def cb(question, answer=None):
223 if question is False or not answer: # dialog cancelled or the answer is empty 250 if question is False or not answer: # dialog cancelled or the answer is empty
224 return 251 return
225 self.smpAuthSecret(answer, question) 252 self.smpAuthSecret(answer, question)
226 text = AUTH_INFO_TXT + AUTH_QUEST_DEF + _("Enter question here:{eol}").format(eol=DIALOG_EOL, question=data) 253 text = (AUTH_INFO_TXT + "<i>" + AUTH_QUEST_DEFINE_TXT + "</i>" + AUTH_QUEST_DEFINE).format(eol=DIALOG_EOL)
227 dialog.PromptDialog(cb, [text, AUTH_SECRET_TXT], title=title, AddStyleName="maxWidthLimit").show() 254 dialog.PromptDialog(cb, [text, AUTH_SECRET_INPUT.format(eol=DIALOG_EOL)], title=title, AddStyleName="maxWidthLimit").show()
228 else: 255 else:
229 def cb(answer): 256 def cb(answer):
230 if not answer: # dialog cancelled or the answer is empty 257 if not answer: # dialog cancelled or the answer is empty
231 self.smpAuthAbort('answered') 258 self.smpAuthAbort('answered')
232 return 259 return
233 self.smpAuthSecret(answer) 260 self.smpAuthSecret(answer)
234 text = AUTH_INFO_TXT + AUTH_QUEST_ASK + _("This is the question asked by your correspondent:{eol}{question}").format(eol=DIALOG_EOL, question=data) 261 text = (AUTH_INFO_TXT + "<i>" + AUTH_QUEST_ANSWER_TXT + "</i>" + AUTH_QUEST_ANSWER).format(eol=DIALOG_EOL, question=data)
235 dialog.PromptDialog(cb, text + AUTH_SECRET_TXT, title=title, AddStyleName="maxWidthLimit").show() 262 dialog.PromptDialog(cb, text + AUTH_SECRET_INPUT.format(eol=DIALOG_EOL), title=title, AddStyleName="maxWidthLimit").show()
236 elif type_ == 'trust': 263 elif type_ == 'trust':
237 self.setCurrentTrust('smp' if data else '', act) 264 self.setCurrentTrust('smp' if data else '', act)
238 elif type_ == 'abort': 265 elif type_ == 'abort':
239 self.setCurrentTrust('', act, 'abort') 266 self.setCurrentTrust('', act, 'abort')
240 267
372 if otrctx.state == otr.context.STATE_ENCRYPTED: 399 if otrctx.state == otr.context.STATE_ENCRYPTED:
373 log.debug(u"encrypting message") 400 log.debug(u"encrypting message")
374 otrctx.sendMessage(msg) 401 otrctx.sendMessage(msg)
375 self.host.newMessageCb(self.host.whoami, msg, msg_type, jid, extra) 402 self.host.newMessageCb(self.host.whoami, msg, msg_type, jid, extra)
376 else: 403 else:
377 feedback = D_("Your message was not sent because your correspondent closed the encrypted conversation on his/her side. Either close your own side, or refresh the session.") 404 feedback = SEND_PLAIN_IN_FINISHED_CONTEXT
378 dialog.InfoDialog(_('Finished encrypted session'), feedback, AddStyleName="maxWidthLimit").show() 405 dialog.InfoDialog(FINISHED_CONTEXT_TITLE.format(jid=to_jid.full()), feedback, AddStyleName="maxWidthLimit").show()
379 else: 406 else:
380 log.debug(u"sending message unencrypted") 407 log.debug(u"sending message unencrypted")
381 self.host.bridge.call('sendMessage', (None, self.host.sendError), to_jid.full(), msg, '', msg_type, extra) 408 self.host.bridge.call('sendMessage', (None, self.host.sendError), to_jid.full(), msg, '', msg_type, extra)
382 409
383 if msg_type != 'groupchat': 410 if msg_type != 'groupchat':
399 @return: True if the session has been finished or disconnected, False if there was nothing to do 426 @return: True if the session has been finished or disconnected, False if there was nothing to do
400 """ 427 """
401 def cb(other_jid): 428 def cb(other_jid):
402 def not_available(): 429 def not_available():
403 if not finish: 430 if not finish:
404 self.host.newMessageCb(other_jid, FEEDBACK_NOT_PRIVATE % other_jid.full(), C.MESS_TYPE_INFO, self.host.whoami, {}) 431 self.host.newMessageCb(other_jid, END_PLAIN.format(jid=other_jid.full()), C.MESS_TYPE_INFO, self.host.whoami, {})
405 432
406 priv_key = self.context_manager.account.privkey 433 priv_key = self.context_manager.account.privkey
407 if priv_key is None: 434 if priv_key is None:
408 not_available() 435 not_available()
409 return 436 return
454 481
455 @param menu_data: %(menu_data)s 482 @param menu_data: %(menu_data)s
456 @param profile: %(doc_profile)s 483 @param profile: %(doc_profile)s
457 """ 484 """
458 def not_available(): 485 def not_available():
459 dialog.InfoDialog(_("No running session"), _("You must start a private conversation before authenticating your correspondent."), AddStyleName="maxWidthLimit").show() 486 dialog.InfoDialog(AUTH_TRUST_NA_TITLE, AUTH_TRUST_NA_TXT, AddStyleName="maxWidthLimit").show()
460 487
461 priv_key = self.context_manager.account.privkey 488 priv_key = self.context_manager.account.privkey
462 if priv_key is None: 489 if priv_key is None:
463 not_available() 490 not_available()
464 return 491 return
490 @param profile: %(doc_profile)s 517 @param profile: %(doc_profile)s
491 """ 518 """
492 priv_key = self.context_manager.account.privkey 519 priv_key = self.context_manager.account.privkey
493 if priv_key is None: 520 if priv_key is None:
494 # we have no private key yet 521 # we have no private key yet
495 dialog.InfoDialog(_("No private key"), _("You don't have any private key yet."), AddStyleName="maxWidthLimit").show() 522 dialog.InfoDialog(KEY_NA_TITLE, KEY_NA_TXT, AddStyleName="maxWidthLimit").show()
496 return 523 return
497 524
498 def cb(to_jid): 525 def cb(to_jid):
499 def dropKey(confirm): 526 def dropKey(confirm):
500 if confirm: 527 if confirm:
501 # we end all sessions 528 # we end all sessions
502 for context in self.context_manager.contexts.values(): 529 for context in self.context_manager.contexts.values():
503 context.disconnect() 530 context.disconnect()
504 self.context_manager.account.privkey = None 531 self.context_manager.account.privkey = None
505 self.context_manager.account.getPrivkey() # as account.privkey are None, getPrivkey will generate a new key, and save it 532 self.context_manager.account.getPrivkey() # as account.privkey are None, getPrivkey will generate a new key, and save it
506 dialog.InfoDialog(_('Private key'), _("Your private key has been dropped."), AddStyleName="maxWidthLimit").show() 533 dialog.InfoDialog(KEY_TITLE, KEY_DROPPED_TXT, AddStyleName="maxWidthLimit").show()
507 534
508 text = _(DROP_TXT) 535 dialog.ConfirmDialog(dropKey, KEY_DROP_TXT.format(eol=DIALOG_EOL), KEY_DROP_TITLE, AddStyleName="maxWidthLimit").show()
509 title = _('Drop your private key')
510 dialog.ConfirmDialog(dropKey, text, title, AddStyleName="maxWidthLimit").show()
511 536
512 try: 537 try:
513 to_jid = menu_data['jid'] 538 to_jid = menu_data['jid']
514 self.fixResource(to_jid, cb) 539 self.fixResource(to_jid, cb)
515 except KeyError: 540 except KeyError: