Message has safe link opening

Links in message body (if in HTML mode) now open, but it asks for a
confirmation in a dialog box.

Fixes #27
This commit is contained in:
mailchuck 2015-12-15 01:24:10 +01:00 committed by Peter Surda
parent 751f9108d8
commit 6557681a6c
2 changed files with 23 additions and 6 deletions

View File

@ -2,16 +2,21 @@ from PyQt4 import QtCore, QtGui
from safehtmlparser import *
class MessageView(QtGui.QTextEdit):
class MessageView(QtGui.QTextBrowser):
MODE_PLAIN = 0
MODE_HTML = 1
TEXT_PLAIN = "HTML detected, click here to display"
TEXT_HTML = "Click here to disable HTML"
CONFIRM_TITLE = "Follow external link"
CONFIRM_TEXT = "The link \"%1\" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure?"
def __init__(self, parent = 0):
super(MessageView, self).__init__(parent)
self.mode = MessageView.MODE_PLAIN
self.html = None
self.setOpenExternalLinks(False)
self.setOpenLinks(False)
self.anchorClicked.connect(self.confirmURL)
def mousePressEvent(self, event):
#text = textCursor.block().text()
@ -22,18 +27,26 @@ class MessageView(QtGui.QTextEdit):
self.showPlain()
else:
super(MessageView, self).mousePressEvent(event)
def confirmURL(self, link):
reply = QtGui.QMessageBox.question(self,
QtGui.QApplication.translate(type(self).__name__, MessageView.CONFIRM_TITLE),
QtGui.QApplication.translate(type(self).__name__, MessageView.CONFIRM_TEXT).arg(str(link.toString())),
QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.Yes:
QtGui.QDesktopServices.openUrl(link)
def showPlain(self):
self.mode = MessageView.MODE_PLAIN
out = self.html.raw
if self.html.has_html:
out = "<div align=\"center\" style=\"text-decoration: underline;\"><b>" + QtGui.QApplication.translate("MessageView", MessageView.TEXT_PLAIN) + "</b></div><br/>" + out
self.setHtml(QtCore.QString(out))
out = "<div align=\"center\" style=\"text-decoration: underline;\"><b>" + QtGui.QApplication.translate(type(self).__name__, MessageView.TEXT_PLAIN) + "</b></div><br/>" + out
self.setHtml(QtCore.QString(out))
def showHTML(self):
self.mode = MessageView.MODE_HTML
out = self.html.sanitised
out = "<div align=\"center\" style=\"text-decoration: underline;\"><b>" + QtGui.QApplication.translate("MessageView", MessageView.TEXT_HTML) + "</b></div><br/>" + out
out = "<div align=\"center\" style=\"text-decoration: underline;\"><b>" + QtGui.QApplication.translate(type(self).__name__, MessageView.TEXT_HTML) + "</b></div><br/>" + out
self.setHtml(QtCore.QString(out))
def setContent(self, data):

View File

@ -39,7 +39,9 @@ class SafeHTMLParser(HTMLParser):
for attr in attrs:
if tag == "img" and attr[0] == "src" and not self.allow_picture:
attr[1] = ""
self.sanitised += " " + quote_plus(attr[0]) + "=\"" + attr[1] + "\""
self.sanitised += " " + quote_plus(attr[0])
if attr[1] is not None:
self.sanitised += "=\"" + attr[1] + "\""
if inspect.stack()[1][3] == "handle_startendtag":
self.sanitised += "/"
self.sanitised += ">"
@ -53,7 +55,9 @@ class SafeHTMLParser(HTMLParser):
for attr in attrs:
if tag == "img" and attr[0] == "src" and not self.allow_picture:
attr[1] = ""
self.raw += " " + attr[0] + "=&quot;" + attr[1] + "&quot;"
self.raw += " " + attr[0]
if attr[1] is not None:
self.raw + "=&quot;" + attr[1] + "&quot;"
if inspect.stack()[1][3] == "handle_startendtag":
self.raw += "/"
self.raw += "&gt;"