From 30f4fbbdb677443268d82e935bfaad5b7af393a0 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 5 Jul 2020 21:07:36 +0100 Subject: [PATCH 01/44] Eyes banner --- img/eyes.jpg | Bin 0 -> 170499 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 img/eyes.jpg diff --git a/img/eyes.jpg b/img/eyes.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e6a304847736a598fc229a76eeb2281499e39536 GIT binary patch literal 170499 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�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 Date: Mon, 6 Jul 2020 10:52:06 +0100 Subject: [PATCH 02/44] Functions for pgp fingerprints --- pgp.py | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 2 deletions(-) diff --git a/pgp.py b/pgp.py index 7f24cc546..a9205606f 100644 --- a/pgp.py +++ b/pgp.py @@ -53,6 +53,28 @@ def getPGPpubKey(actorJson: {}) -> str: return '' +def getPGPfingerprint(actorJson: {}) -> str: + """Returns PGP fingerprint for the given actor + """ + if not actorJson.get('attachment'): + return '' + for propertyValue in actorJson['attachment']: + if not propertyValue.get('name'): + continue + if not propertyValue['name'].lower().startswith('openpgp'): + continue + if not propertyValue.get('type'): + continue + if not propertyValue.get('value'): + continue + if propertyValue['type'] != 'PropertyValue': + continue + if len(propertyValue['value']) < 10: + continue + return propertyValue['value'] + return '' + + def setEmailAddress(actorJson: {}, emailAddress: str) -> None: """Sets the email address for the given actor """ @@ -103,6 +125,13 @@ def setEmailAddress(actorJson: {}, emailAddress: str) -> None: def setPGPpubKey(actorJson: {}, PGPpubKey: str) -> None: """Sets a PGP public key for the given actor """ + removeKey = False + if not PGPpubKey: + removeKey = True + else: + if '--BEGIN PGP PUBLIC KEY' not in PGPpubKey: + removeKey = True + if not actorJson.get('attachment'): actorJson['attachment'] = [] @@ -119,8 +148,7 @@ def setPGPpubKey(actorJson: {}, PGPpubKey: str) -> None: break if propertyFound: actorJson['attachment'].remove(propertyValue) - - if '--BEGIN PGP PUBLIC KEY' not in PGPpubKey: + if removeKey: return for propertyValue in actorJson['attachment']: @@ -141,3 +169,52 @@ def setPGPpubKey(actorJson: {}, PGPpubKey: str) -> None: "value": PGPpubKey } actorJson['attachment'].append(newPGPpubKey) + + +def setPGPfingerprint(actorJson: {}, fingerprint: str) -> None: + """Sets a PGP fingerprint for the given actor + """ + removeFingerprint = False + if not fingerprint: + removeFingerprint = True + else: + if len(fingerprint) < 10: + removeFingerprint = True + + if not actorJson.get('attachment'): + actorJson['attachment'] = [] + + # remove any existing value + propertyFound = None + for propertyValue in actorJson['attachment']: + if not propertyValue.get('name'): + continue + if not propertyValue.get('type'): + continue + if not propertyValue['name'].lower().startswith('openpgp'): + continue + propertyFound = propertyValue + break + if propertyFound: + actorJson['attachment'].remove(propertyValue) + if removeFingerprint: + return + + for propertyValue in actorJson['attachment']: + if not propertyValue.get('name'): + continue + if not propertyValue.get('type'): + continue + if not propertyValue['name'].lower().startswith('openpgp'): + continue + if propertyValue['type'] != 'PropertyValue': + continue + propertyValue['value'] = fingerprint.strip() + return + + newPGPfingerprint = { + "name": "OpenPGP", + "type": "PropertyValue", + "value": fingerprint + } + actorJson['attachment'].append(newPGPfingerprint) From c34aa81962d2916decfd698524458d6c4c98590a Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Mon, 6 Jul 2020 11:14:41 +0100 Subject: [PATCH 03/44] PGP fingerprint in profile --- daemon.py | 18 +++++++++++++++++- translations/ar.json | 1 + translations/ca.json | 1 + translations/cy.json | 1 + translations/de.json | 1 + translations/en.json | 3 ++- translations/es.json | 1 + translations/fr.json | 1 + translations/ga.json | 1 + translations/hi.json | 3 ++- translations/it.json | 1 + translations/ja.json | 1 + translations/oc.json | 1 + translations/pt.json | 1 + translations/ru.json | 1 + translations/zh.json | 1 + webinterface.py | 21 ++++++++++++++++++++- 17 files changed, 54 insertions(+), 4 deletions(-) diff --git a/daemon.py b/daemon.py index df1dd3ba5..53a9ae6a0 100644 --- a/daemon.py +++ b/daemon.py @@ -30,7 +30,9 @@ from metadata import metaDataNodeInfo from pgp import getEmailAddress from pgp import setEmailAddress from pgp import getPGPpubKey +from pgp import getPGPfingerprint from pgp import setPGPpubKey +from pgp import setPGPfingerprint from xmpp import getXmppAddress from xmpp import setXmppAddress from ssb import getSSBAddress @@ -1549,6 +1551,7 @@ class PubServer(BaseHTTPRequestHandler): optionsLink = optionsList[3] donateUrl = None PGPpubKey = None + PGPfingerprint = None xmppAddress = None matrixAddress = None blogAddress = None @@ -1567,6 +1570,7 @@ class PubServer(BaseHTTPRequestHandler): toxAddress = getToxAddress(actorJson) emailAddress = getEmailAddress(actorJson) PGPpubKey = getPGPpubKey(actorJson) + PGPfingerprint = getPGPfingerprint(actorJson) msg = htmlPersonOptions(self.server.translate, self.server.baseDir, self.server.domain, @@ -1577,7 +1581,8 @@ class PubServer(BaseHTTPRequestHandler): pageNumber, donateUrl, xmppAddress, matrixAddress, ssbAddress, blogAddress, - toxAddress, PGPpubKey, + toxAddress, + PGPpubKey, PGPfingerprint, emailAddress).encode('utf-8') self._set_headers('text/html', len(msg), cookie, callingDomain) @@ -6242,6 +6247,17 @@ class PubServer(BaseHTTPRequestHandler): setPGPpubKey(actorJson, '') actorChanged = True + currentPGPfingerprint = getPGPfingerprint(actorJson) + if fields.get('openpgp'): + if fields['openpgp'] != currentPGPfingerprint: + setPGPfingerprint(actorJson, + fields['openpgp']) + actorChanged = True + else: + if currentPGPfingerprint: + setPGPfingerprint(actorJson, '') + actorChanged = True + currentDonateUrl = getDonationUrl(actorJson) if fields.get('donateUrl'): if fields['donateUrl'] != currentDonateUrl: diff --git a/translations/ar.json b/translations/ar.json index 60bc5a4e4..54d95f0fe 100644 --- a/translations/ar.json +++ b/translations/ar.json @@ -206,6 +206,7 @@ "Matrix": "Matrix", "Email": "البريد الإلكتروني", "PGP": "PGP", + "PGP Fingerprint": "بصمة PGP", "This is a scheduled post.": "هذا هو المقرر المقرر.", "Remove scheduled posts": "إزالة المشاركات المجدولة", "Remove Twitter posts": "إزالة مشاركات Twitter", diff --git a/translations/ca.json b/translations/ca.json index 844521d30..dd8dda946 100644 --- a/translations/ca.json +++ b/translations/ca.json @@ -206,6 +206,7 @@ "Matrix": "Matrix", "Email": "Correu electrònic", "PGP": "PGP", + "PGP Fingerprint": "Empremta digital PGP", "This is a scheduled post.": "Aquesta és una publicació programada.", "Remove scheduled posts": "Elimineu les publicacions programades", "Remove Twitter posts": "Elimina les publicacions de Twitter", diff --git a/translations/cy.json b/translations/cy.json index f7536e907..cdf3f64ed 100644 --- a/translations/cy.json +++ b/translations/cy.json @@ -206,6 +206,7 @@ "Matrix": "Matrix", "Email": "E-bost", "PGP": "PGP", + "PGP Fingerprint": "Olion Bysedd PGP", "This is a scheduled post.": "Mae hon yn swydd wedi'i hamserlennu.", "Remove scheduled posts": "Tynnwch y swyddi a drefnwyd", "Remove Twitter posts": "Dileu postiadau Twitter", diff --git a/translations/de.json b/translations/de.json index f784ebbf4..846c781a8 100644 --- a/translations/de.json +++ b/translations/de.json @@ -206,6 +206,7 @@ "Matrix": "Matrix", "Email": "Email", "PGP": "PGP", + "PGP Fingerprint": "PGP Fingerabdruck", "This is a scheduled post.": "Dies ist ein geplanter Beitrag.", "Remove scheduled posts": "Geplante Posts entfernen", "Remove Twitter posts": "Entfernen Sie Twitter-Posts", diff --git a/translations/en.json b/translations/en.json index e11d6ade8..a8f3c2f7e 100644 --- a/translations/en.json +++ b/translations/en.json @@ -205,7 +205,8 @@ "XMPP": "XMPP", "Matrix": "Matrix", "Email": "Email", - "PGP": "PGP", + "PGP": "PGP Key", + "PGP Fingerprint": "PGP Fingerprint", "This is a scheduled post.": "This is a scheduled post.", "Remove scheduled posts": "Remove scheduled posts", "Remove Twitter posts": "Remove Twitter posts", diff --git a/translations/es.json b/translations/es.json index dc5801012..d3c74acef 100644 --- a/translations/es.json +++ b/translations/es.json @@ -206,6 +206,7 @@ "Matrix": "Matrix", "Email": "Email", "PGP": "PGP", + "PGP Fingerprint": "Huella digital PGP", "This is a scheduled post.": "Esta es una publicación programada.", "Remove scheduled posts": "Eliminar publicaciones programadas", "Remove Twitter posts": "Eliminar publicaciones de Twitter", diff --git a/translations/fr.json b/translations/fr.json index a9cbcb8a2..1ce7efc35 100644 --- a/translations/fr.json +++ b/translations/fr.json @@ -206,6 +206,7 @@ "Matrix": "Matrix", "Email": "Email", "PGP": "PGP", + "PGP Fingerprint": "Empreinte digitale PGP", "This is a scheduled post.": "Il s'agit d'un article programmé.", "Remove scheduled posts": "Supprimer les messages planifiés", "Remove Twitter posts": "Supprimer les messages Twitter", diff --git a/translations/ga.json b/translations/ga.json index 603202d8c..d8073b3af 100644 --- a/translations/ga.json +++ b/translations/ga.json @@ -206,6 +206,7 @@ "Matrix": "Matrix", "Email": "Ríomhphost", "PGP": "PGP", + "PGP Fingerprint": "Méarlorg PGP", "This is a scheduled post.": "Is post sceidealta é seo.", "Remove scheduled posts": "Bain na poist sceidealta", "Remove Twitter posts": "Bain poist Twitter", diff --git a/translations/hi.json b/translations/hi.json index 9f02c144b..d28e07681 100644 --- a/translations/hi.json +++ b/translations/hi.json @@ -205,7 +205,8 @@ "XMPP": "XMPP", "Matrix": "Matrix", "Email": "ईमेल", - "PGP": "PGP", + "PGP": "पीजीपी", + "PGP Fingerprint": "पीजीपी फिंगरप्रिंट", "This is a scheduled post.": "यह एक अनुसूचित पद है।", "Remove scheduled posts": "अनुसूचित पदों को हटा दें", "Remove Twitter posts": "ट्विटर पोस्ट हटाएं", diff --git a/translations/it.json b/translations/it.json index 3fe48c28c..92a91a40a 100644 --- a/translations/it.json +++ b/translations/it.json @@ -206,6 +206,7 @@ "Matrix": "Matrix", "Email": "E-mail", "PGP": "PGP", + "PGP Fingerprint": "Impronta digitale PGP", "This is a scheduled post.": "Questo è un post programmato", "Remove scheduled posts": "Rimuovi i post programmati", "Remove Twitter posts": "Rimuovi i post di Twitter", diff --git a/translations/ja.json b/translations/ja.json index f3e6d6bb6..d7bb800b6 100644 --- a/translations/ja.json +++ b/translations/ja.json @@ -206,6 +206,7 @@ "Matrix": "Matrix", "Email": "Eメール", "PGP": "PGP", + "PGP Fingerprint": "PGPフィンガープリント", "This is a scheduled post.": "これはスケジュールされた投稿です。", "Remove scheduled posts": "スケジュールされた投稿を削除する", "Remove Twitter posts": "Twitterの投稿を削除する", diff --git a/translations/oc.json b/translations/oc.json index ba8b1c550..cb288851d 100644 --- a/translations/oc.json +++ b/translations/oc.json @@ -202,6 +202,7 @@ "Matrix": "Matrix", "Email": "Email", "PGP": "PGP", + "PGP Fingerprint": "PGP Fingerprint", "This is a scheduled post.": "This is a scheduled post.", "Remove scheduled posts": "Remove scheduled posts", "Remove Twitter posts": "Remove Twitter posts", diff --git a/translations/pt.json b/translations/pt.json index 2f9c5b5e8..ccbc94ddc 100644 --- a/translations/pt.json +++ b/translations/pt.json @@ -206,6 +206,7 @@ "Matrix": "Matrix", "Email": "Email", "PGP": "PGP", + "PGP Fingerprint": "Impressão digital PGP", "This is a scheduled post.": "Esta é uma postagem agendada.", "Remove scheduled posts": "Remover postagens agendadas", "Remove Twitter posts": "Remover postagens do Twitter", diff --git a/translations/ru.json b/translations/ru.json index 290f301fa..616e621e2 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -206,6 +206,7 @@ "Matrix": "Matrix", "Email": "Эл. адрес", "PGP": "PGP", + "PGP Fingerprint": "PGP Отпечаток пальца", "This is a scheduled post.": "Это запланированный пост.", "Remove scheduled posts": "Удалить запланированные сообщения", "Remove Twitter posts": "Удалить сообщения из Твиттера", diff --git a/translations/zh.json b/translations/zh.json index bd0ba1eb5..c378bd5b6 100644 --- a/translations/zh.json +++ b/translations/zh.json @@ -205,6 +205,7 @@ "Matrix": "Matrix", "Email": "电子邮件", "PGP": "PGP", + "PGP Fingerprint": "PGP指纹", "This is a scheduled post.": "这是预定的帖子。", "Remove scheduled posts": "删除预定的帖子", "Remove Twitter posts": "删除Twitter帖子", diff --git a/webinterface.py b/webinterface.py index 95604f7e5..a8f7521aa 100644 --- a/webinterface.py +++ b/webinterface.py @@ -19,6 +19,7 @@ from person import personBoxJson from person import isPersonSnoozed from pgp import getEmailAddress from pgp import getPGPpubKey +from pgp import getPGPfingerprint from xmpp import getXmppAddress from ssb import getSSBAddress from tox import getToxAddress @@ -1050,6 +1051,7 @@ def htmlEditProfile(translate: {}, baseDir: str, path: str, donateUrl = '' emailAddress = '' PGPpubKey = '' + PGPfingerprint = '' xmppAddress = '' matrixAddress = '' ssbAddress = '' @@ -1066,6 +1068,7 @@ def htmlEditProfile(translate: {}, baseDir: str, path: str, toxAddress = getToxAddress(actorJson) emailAddress = getEmailAddress(actorJson) PGPpubKey = getPGPpubKey(actorJson) + PGPfingerprint = getPGPfingerprint(actorJson) if actorJson.get('name'): displayNickname = actorJson['name'] if actorJson.get('summary'): @@ -1331,6 +1334,12 @@ def htmlEditProfile(translate: {}, baseDir: str, path: str, translate['Email'] + '
' editProfileForm += \ ' ' + editProfileForm += \ + '
' + editProfileForm += \ + ' ' editProfileForm += \ '
' editProfileForm += \ @@ -2550,13 +2559,15 @@ def htmlProfile(defaultTimeline: str, donateSection = '' donateUrl = getDonationUrl(profileJson) PGPpubKey = getPGPpubKey(profileJson) + PGPfingerprint = getPGPfingerprint(profileJson) emailAddress = getEmailAddress(profileJson) xmppAddress = getXmppAddress(profileJson) matrixAddress = getMatrixAddress(profileJson) ssbAddress = getSSBAddress(profileJson) toxAddress = getToxAddress(profileJson) if donateUrl or xmppAddress or matrixAddress or \ - ssbAddress or toxAddress or PGPpubKey or emailAddress: + ssbAddress or toxAddress or PGPpubKey or \ + PGPfingerprint or emailAddress: donateSection = '

\n' donateSection += '
\n' if donateUrl: @@ -2583,6 +2594,10 @@ def htmlProfile(defaultTimeline: str, donateSection += \ '

Tox:

\n' + if PGPfingerprint: + donateSection += \ + '

PGP: ' + \ + PGPfingerprint.replace('\n', '
') + '

\n' if PGPpubKey: donateSection += \ '

' + PGPpubKey.replace('\n', '
') + '

\n' @@ -5314,6 +5329,7 @@ def htmlPersonOptions(translate: {}, baseDir: str, blogAddress: str, toxAddress: str, PGPpubKey: str, + PGPfingerprint: str, emailAddress) -> str: """Show options for a person: view/follow/block/report """ @@ -5411,6 +5427,9 @@ def htmlPersonOptions(translate: {}, baseDir: str, if toxAddress: optionsStr += \ '

Tox: ' + toxAddress + '

' + if PGPfingerprint: + optionsStr += '

PGP: ' + \ + PGPfingerprint.replace('\n', '
') + '

' if PGPpubKey: optionsStr += '

' + \ PGPpubKey.replace('\n', '
') + '

' From bacc38eff2e935ffe7137c2b9a857a2d3c2cdea0 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Mon, 6 Jul 2020 11:21:09 +0100 Subject: [PATCH 04/44] Remove tox address if invalid --- tox.py | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/tox.py b/tox.py index fe37a8fe6..1be44754d 100644 --- a/tox.py +++ b/tox.py @@ -43,6 +43,21 @@ def getToxAddress(actorJson: {}) -> str: def setToxAddress(actorJson: {}, toxAddress: str) -> None: """Sets an tox address for the given actor """ + notToxAddress = False + + if len(toxAddress) != 76: + notToxAddress = True + if toxAddress.upper() != toxAddress: + notToxAddress = True + if '"' in toxAddress: + notToxAddress = True + if ' ' in toxAddress: + notToxAddress = True + if '.' in toxAddress: + notToxAddress = True + if ',' in toxAddress: + notToxAddress = True + if not actorJson.get('attachment'): actorJson['attachment'] = [] @@ -59,18 +74,7 @@ def setToxAddress(actorJson: {}, toxAddress: str) -> None: break if propertyFound: actorJson['attachment'].remove(propertyFound) - - if len(toxAddress) != 76: - return - if toxAddress.upper() != toxAddress: - return - if '"' in toxAddress: - return - if ' ' in toxAddress: - return - if '.' in toxAddress: - return - if ',' in toxAddress: + if notToxAddress: return for propertyValue in actorJson['attachment']: From 1a347ac87850d5f36ece435ed80665af0c7d437c Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Mon, 6 Jul 2020 11:23:11 +0100 Subject: [PATCH 05/44] Remove ssb address if invalid --- ssb.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/ssb.py b/ssb.py index 0f393044c..93f2e4935 100644 --- a/ssb.py +++ b/ssb.py @@ -41,6 +41,18 @@ def getSSBAddress(actorJson: {}) -> str: def setSSBAddress(actorJson: {}, ssbAddress: str) -> None: """Sets an ssb address for the given actor """ + notSSBAddress = False + if not ssbAddress.startswith('@'): + notSSBAddress = True + if '=.' not in ssbAddress: + notSSBAddress = True + if '"' in ssbAddress: + notSSBAddress = True + if ' ' in ssbAddress: + notSSBAddress = True + if ',' in ssbAddress: + notSSBAddress = True + if not actorJson.get('attachment'): actorJson['attachment'] = [] @@ -57,16 +69,7 @@ def setSSBAddress(actorJson: {}, ssbAddress: str) -> None: break if propertyFound: actorJson['attachment'].remove(propertyFound) - - if not ssbAddress.startswith('@'): - return - if '=.' not in ssbAddress: - return - if '"' in ssbAddress: - return - if ' ' in ssbAddress: - return - if ',' in ssbAddress: + if notSSBAddress: return for propertyValue in actorJson['attachment']: From dd8650b717f089bd99f216ab9f93516b01f9aa0d Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Mon, 6 Jul 2020 11:25:18 +0100 Subject: [PATCH 06/44] Remove email address if invalid --- pgp.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/pgp.py b/pgp.py index a9205606f..f8dad7261 100644 --- a/pgp.py +++ b/pgp.py @@ -78,6 +78,14 @@ def getPGPfingerprint(actorJson: {}) -> str: def setEmailAddress(actorJson: {}, emailAddress: str) -> None: """Sets the email address for the given actor """ + notEmailAddress = False + if '@' not in emailAddress: + notEmailAddress = True + if '.' not in emailAddress: + notEmailAddress = True + if emailAddress.startswith('@'): + notEmailAddress = True + if not actorJson.get('attachment'): actorJson['attachment'] = [] @@ -94,12 +102,7 @@ def setEmailAddress(actorJson: {}, emailAddress: str) -> None: break if propertyFound: actorJson['attachment'].remove(propertyFound) - - if '@' not in emailAddress: - return - if '.' not in emailAddress: - return - if emailAddress.startswith('@'): + if notEmailAddress: return for propertyValue in actorJson['attachment']: From d20326208454f4ada4431b9d1b38a4951e3e56da Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Mon, 6 Jul 2020 11:27:10 +0100 Subject: [PATCH 07/44] Remove XMPP address if invalid --- xmpp.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/xmpp.py b/xmpp.py index 58dd6a99a..7972a4ad1 100644 --- a/xmpp.py +++ b/xmpp.py @@ -36,6 +36,14 @@ def getXmppAddress(actorJson: {}) -> str: def setXmppAddress(actorJson: {}, xmppAddress: str) -> None: """Sets an xmpp address for the given actor """ + notXmppAddress = False + if '@' not in xmppAddress: + notXmppAddress = True + if '.' not in xmppAddress: + notXmppAddress = True + if '"' in xmppAddress: + notXmppAddress = True + if not actorJson.get('attachment'): actorJson['attachment'] = [] @@ -53,12 +61,7 @@ def setXmppAddress(actorJson: {}, xmppAddress: str) -> None: break if propertyFound: actorJson['attachment'].remove(propertyFound) - - if '@' not in xmppAddress: - return - if '.' not in xmppAddress: - return - if '"' in xmppAddress: + if notXmppAddress: return for propertyValue in actorJson['attachment']: From be39532262b1095740635ed18fb2124c15463a32 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Mon, 6 Jul 2020 11:31:00 +0100 Subject: [PATCH 08/44] Remove donation url if invalid --- donate.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/donate.py b/donate.py index 48298a9f7..db68f9680 100644 --- a/donate.py +++ b/donate.py @@ -41,6 +41,14 @@ def getDonationUrl(actorJson: {}) -> str: def setDonationUrl(actorJson: {}, donateUrl: str) -> None: """Sets a link used for donations """ + notUrl = False + if '.' not in donateUrl: + notUrl = True + if '://' not in donateUrl: + notUrl = True + if ' ' in donateUrl: + notUrl = True + if not actorJson.get('attachment'): actorJson['attachment'] = [] @@ -65,6 +73,8 @@ def setDonationUrl(actorJson: {}, donateUrl: str) -> None: break if propertyFound: actorJson['attachment'].remove(propertyFound) + if notUrl: + return donateValue = \ '
': + removing = False + elif not removing: + result += ch + return result + + def removeLongWords(content: str, maxWordLength: int, longWordsList: []) -> str: """Breaks up long words so that on mobile screens this doesn't diff --git a/daemon.py b/daemon.py index 53a9ae6a0..64aa7263f 100644 --- a/daemon.py +++ b/daemon.py @@ -747,7 +747,7 @@ class PubServer(BaseHTTPRequestHandler): self._write(msg) print('instance metadata sent') return True - if self.path.startswith('/api/v1/instance/peers'): + if self.path.startswith('/api/v1/instance/peers'): # This is just a dummy result. # Showing the full list of peers would have privacy implications. # On a large instance you are somewhat lost in the crowd, but on diff --git a/tests.py b/tests.py index a0a60dfd0..ba21720bc 100644 --- a/tests.py +++ b/tests.py @@ -64,6 +64,7 @@ from media import getAttachmentMediaType from delete import sendDeleteViaServer from inbox import validInbox from inbox import validInboxFilenames +from content import removeHtml from content import addWebLinks from content import replaceEmojiFromTags from content import addHtmlTags @@ -1873,8 +1874,18 @@ def testSiteIsActive(): assert(not siteIsActive('https://notarealwebsite.a.b.c')) +def testRemoveHtml(): + print('testRemoveHtml') + testStr = 'This string has no html.' + assert(removeHtml(testStr) == testStr) + testStr = 'This string has html.' + print(removeHtml(testStr)) + assert(removeHtml(testStr) == 'This string has html.') + + def runAllTests(): print('Running tests...') + testRemoveHtml() testSiteIsActive() testJsonld() testRemoveTextFormatting() diff --git a/webinterface.py b/webinterface.py index a8f7521aa..dad767950 100644 --- a/webinterface.py +++ b/webinterface.py @@ -63,6 +63,7 @@ from content import getMentionsFromHtml from content import addHtmlTags from content import replaceEmojiFromTags from content import removeLongWords +from content import removeHtml from config import getConfigParam from skills import getSkills from cache import getPersonFromCache @@ -6215,6 +6216,8 @@ def htmlProfileAfterSearch(recentPostsCache: {}, maxRecentPosts: int, profileJson['summary'].replace('
', '\n') avatarDescription = avatarDescription.replace('

', '') avatarDescription = avatarDescription.replace('

', '') + if '<' in avatarDescription: + avatarDescription = removeHtml(avatarDescription) profileStr = '
' profileStr += '
' if avatarUrl: From 4af8ce9d5ffa9913e3983d88fc59e6f9b574268e Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Tue, 7 Jul 2020 15:19:09 +0100 Subject: [PATCH 10/44] Tidying --- daemon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon.py b/daemon.py index 64aa7263f..53a9ae6a0 100644 --- a/daemon.py +++ b/daemon.py @@ -747,7 +747,7 @@ class PubServer(BaseHTTPRequestHandler): self._write(msg) print('instance metadata sent') return True - if self.path.startswith('/api/v1/instance/peers'): + if self.path.startswith('/api/v1/instance/peers'): # This is just a dummy result. # Showing the full list of peers would have privacy implications. # On a large instance you are somewhat lost in the crowd, but on From b835e161e9389994d813cf52b1bfb451a23e04df Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 10:21:36 +0100 Subject: [PATCH 11/44] Posts option can accept actor --- epicyon.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/epicyon.py b/epicyon.py index 663b5064c..0aec050d6 100644 --- a/epicyon.py +++ b/epicyon.py @@ -386,8 +386,16 @@ if baseDir.endswith('/'): if args.posts: if '@' not in args.posts: - print('Syntax: --posts nickname@domain') - sys.exit() + if '/users/' in args.posts: + postsNickname = getNicknameFromActor(args.posts) + postsDomain, postsPort = getDomainFromActor(args.posts) + args.posts = postsNickname + '@' + postsDomain + if postsPort: + if postsPort != 80 and postsPort != 443: + args.posts += ':' + str(postsPort) + else: + print('Syntax: --posts nickname@domain') + sys.exit() if not args.http: args.port = 443 nickname = args.posts.split('@')[0] @@ -395,8 +403,12 @@ if args.posts: proxyType = None if args.tor or domain.endswith('.onion'): proxyType = 'tor' + if domain.endswith('.onion'): + args.port = 80 elif args.i2p or domain.endswith('.i2p'): proxyType = 'i2p' + if domain.endswith('.i2p'): + args.port = 80 elif args.gnunet: proxyType = 'gnunet' getPublicPostsOfPerson(baseDir, nickname, domain, False, True, From df48983aaef20eb5ae620dd3cecfcb05e65d4f17 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 11:09:51 +0100 Subject: [PATCH 12/44] Option to list referenced domains --- epicyon.py | 39 +++++++++++++++++++++ posts.py | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+) diff --git a/epicyon.py b/epicyon.py index 0aec050d6..d65135068 100644 --- a/epicyon.py +++ b/epicyon.py @@ -15,6 +15,7 @@ from person import deactivateAccount from skills import setSkillLevel from roles import setRole from webfinger import webfingerHandle +from posts import getPublicPostDomains from posts import sendBlockViaServer from posts import sendUndoBlockViaServer from posts import createPublicPost @@ -146,6 +147,10 @@ parser.add_argument('--actor', dest='actor', type=str, parser.add_argument('--posts', dest='posts', type=str, default=None, help='Show posts for the given handle') +parser.add_argument('--postDomains', dest='postDomains', type=str, + default=None, + help='Show domains referenced in public ' + 'posts for the given handle') parser.add_argument('--postsraw', dest='postsraw', type=str, default=None, help='Show raw json of posts for the given handle') @@ -416,6 +421,40 @@ if args.posts: __version__) sys.exit() +if args.postDomains: + if '@' not in args.postDomains: + if '/users/' in args.postDomains: + postsNickname = getNicknameFromActor(args.posts) + postsDomain, postsPort = getDomainFromActor(args.posts) + args.postDomains = postsNickname + '@' + postsDomain + if postsPort: + if postsPort != 80 and postsPort != 443: + args.postDomains += ':' + str(postsPort) + else: + print('Syntax: --posts nickname@domain') + sys.exit() + if not args.http: + args.port = 443 + nickname = args.postDomains.split('@')[0] + domain = args.postDomains.split('@')[1] + proxyType = None + if args.tor or domain.endswith('.onion'): + proxyType = 'tor' + if domain.endswith('.onion'): + args.port = 80 + elif args.i2p or domain.endswith('.i2p'): + proxyType = 'i2p' + if domain.endswith('.i2p'): + args.port = 80 + elif args.gnunet: + proxyType = 'gnunet' + domainList = getPublicPostDomains(baseDir, nickname, domain, False, True, + proxyType, args.port, httpPrefix, debug, + __version__) + for postDomain in domainList: + print(postDomain) + sys.exit() + if args.postsraw: if '@' not in args.postsraw: print('Syntax: --postsraw nickname@domain') diff --git a/posts.py b/posts.py index 31319e828..3754cd827 100644 --- a/posts.py +++ b/posts.py @@ -440,6 +440,58 @@ def getPosts(session, outboxUrl: str, maxPosts: int, return personPosts +def getPostDomains(session, outboxUrl: str, maxPosts: int, + maxMentions: int, + maxEmoji: int, maxAttachments: int, + federationList: [], + personCache: {}, raw: bool, + simple: bool, debug: bool, + projectVersion: str, httpPrefix: str, + domain: str) -> []: + """Returns a list of domains referenced within public posts + """ + if not outboxUrl: + return [] + profileStr = 'https://www.w3.org/ns/activitystreams' + asHeader = { + 'Accept': 'application/activity+json; profile="' + profileStr + '"' + } + if '/outbox/' in outboxUrl: + asHeader = { + 'Accept': 'application/ld+json; profile="' + profileStr + '"' + } + + postDomains = [] + + i = 0 + userFeed = parseUserFeed(session, outboxUrl, asHeader, + projectVersion, httpPrefix, domain) + for item in userFeed: + if not item.get('object'): + continue + if not isinstance(item['object'], dict): + continue + if item['object'].get('inReplyTo'): + postDomain, postPort = \ + getDomainFromActor(item['object']['inReplyTo']) + if postDomain not in postDomains: + postDomains.append(postDomain) + + if item['object'].get('tag'): + for tagItem in item['object']['tag']: + tagType = tagItem['type'].lower() + if tagType == 'mention': + if tagItem.get('href'): + postDomain, postPort = \ + getDomainFromActor(tagItem['href']) + if postDomain not in postDomains: + postDomains.append(postDomain) + i += 1 + if i == maxPosts: + break + return postDomains + + def deleteAllPosts(baseDir: str, nickname: str, domain: str, boxname: str) -> None: """Deletes all posts for a person from inbox or outbox @@ -2933,6 +2985,54 @@ def getPublicPostsOfPerson(baseDir: str, nickname: str, domain: str, projectVersion, httpPrefix, domain) +def getPublicPostDomains(baseDir: str, nickname: str, domain: str, + raw: bool, simple: bool, proxyType: str, + port: int, httpPrefix: str, + debug: bool, projectVersion: str) -> []: + """ Returns a list of domains referenced within public posts + """ + session = createSession(proxyType) + if not session: + return + personCache = {} + cachedWebfingers = {} + federationList = [] + + domainFull = domain + if port: + if port != 80 and port != 443: + if ':' not in domain: + domainFull = domain + ':' + str(port) + handle = httpPrefix + "://" + domainFull + "/@" + nickname + wfRequest = \ + webfingerHandle(session, handle, httpPrefix, cachedWebfingers, + domain, projectVersion) + if not wfRequest: + return [] + if not isinstance(wfRequest, dict): + print('Webfinger for ' + handle + ' did not return a dict. ' + + str(wfRequest)) + return [] + + (personUrl, pubKeyId, pubKey, + personId, shaedInbox, + capabilityAcquisition, + avatarUrl, displayName) = getPersonBox(baseDir, session, wfRequest, + personCache, + projectVersion, httpPrefix, + nickname, domain, 'outbox') + maxMentions = 99 + maxEmoji = 99 + maxAttachments = 5 + postDomains = \ + getPostDomains(session, personUrl, 60, maxMentions, maxEmoji, + maxAttachments, federationList, + personCache, raw, simple, debug, + projectVersion, httpPrefix, domain) + postDomains.sort() + return postDomains + + def sendCapabilitiesUpdate(session, baseDir: str, httpPrefix: str, nickname: str, domain: str, port: int, followerUrl, updateCaps: [], From a82d487b1f8ec00b9015f40c3fb405fe82ffe495 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 11:16:48 +0100 Subject: [PATCH 13/44] Document domains option --- README_commandline.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README_commandline.md b/README_commandline.md index 2fbcff053..8965091a1 100644 --- a/README_commandline.md +++ b/README_commandline.md @@ -136,6 +136,14 @@ If you want to view the raw json: python3 epicyon.py --postsraw nickname@domain ``` +## Listing referenced domains + +To list the domains referenced in public posts: + +``` bash +python3 epicyon.py --postDomains nickname@domain +``` + ## Delete posts To delete a post which you wrote you must first know its url. It is usually something like: From 66204e96dc5a7a5eb68e06ff8bf62e588c5b84b4 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 11:17:30 +0100 Subject: [PATCH 14/44] Syntax --- epicyon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/epicyon.py b/epicyon.py index d65135068..74f02cf3c 100644 --- a/epicyon.py +++ b/epicyon.py @@ -431,7 +431,7 @@ if args.postDomains: if postsPort != 80 and postsPort != 443: args.postDomains += ':' + str(postsPort) else: - print('Syntax: --posts nickname@domain') + print('Syntax: --postDomains nickname@domain') sys.exit() if not args.http: args.port = 443 From b1516507f8cb228ac637281b396daf01c569e7bd Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 11:30:29 +0100 Subject: [PATCH 15/44] Allow for accumulating domains --- epicyon.py | 3 ++- posts.py | 17 +++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/epicyon.py b/epicyon.py index 74f02cf3c..ef4d539bf 100644 --- a/epicyon.py +++ b/epicyon.py @@ -448,9 +448,10 @@ if args.postDomains: args.port = 80 elif args.gnunet: proxyType = 'gnunet' + domainList = [] domainList = getPublicPostDomains(baseDir, nickname, domain, False, True, proxyType, args.port, httpPrefix, debug, - __version__) + __version__, domainList) for postDomain in domainList: print(postDomain) sys.exit() diff --git a/posts.py b/posts.py index 3754cd827..1ed3541b5 100644 --- a/posts.py +++ b/posts.py @@ -447,7 +447,7 @@ def getPostDomains(session, outboxUrl: str, maxPosts: int, personCache: {}, raw: bool, simple: bool, debug: bool, projectVersion: str, httpPrefix: str, - domain: str) -> []: + domain: str, domainList=[]) -> []: """Returns a list of domains referenced within public posts """ if not outboxUrl: @@ -461,7 +461,7 @@ def getPostDomains(session, outboxUrl: str, maxPosts: int, 'Accept': 'application/ld+json; profile="' + profileStr + '"' } - postDomains = [] + postDomains = domainList i = 0 userFeed = parseUserFeed(session, outboxUrl, asHeader, @@ -2988,12 +2988,13 @@ def getPublicPostsOfPerson(baseDir: str, nickname: str, domain: str, def getPublicPostDomains(baseDir: str, nickname: str, domain: str, raw: bool, simple: bool, proxyType: str, port: int, httpPrefix: str, - debug: bool, projectVersion: str) -> []: + debug: bool, projectVersion: str, + domainList=[]) -> []: """ Returns a list of domains referenced within public posts """ session = createSession(proxyType) if not session: - return + return domainList personCache = {} cachedWebfingers = {} federationList = [] @@ -3008,11 +3009,11 @@ def getPublicPostDomains(baseDir: str, nickname: str, domain: str, webfingerHandle(session, handle, httpPrefix, cachedWebfingers, domain, projectVersion) if not wfRequest: - return [] + return domainList if not isinstance(wfRequest, dict): print('Webfinger for ' + handle + ' did not return a dict. ' + str(wfRequest)) - return [] + return domainList (personUrl, pubKeyId, pubKey, personId, shaedInbox, @@ -3025,10 +3026,10 @@ def getPublicPostDomains(baseDir: str, nickname: str, domain: str, maxEmoji = 99 maxAttachments = 5 postDomains = \ - getPostDomains(session, personUrl, 60, maxMentions, maxEmoji, + getPostDomains(session, personUrl, 64, maxMentions, maxEmoji, maxAttachments, federationList, personCache, raw, simple, debug, - projectVersion, httpPrefix, domain) + projectVersion, httpPrefix, domain, domainList) postDomains.sort() return postDomains From 7b06a3b2620ab0f7a4b795d6b6b4e64e0db21a5b Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 13:28:41 +0100 Subject: [PATCH 16/44] Plotting federated instances --- README_commandline.md | 9 +++++ epicyon.py | 31 ++++++++++++++-- posts.py | 29 ++++++++------- socnet.py | 83 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 137 insertions(+), 15 deletions(-) create mode 100644 socnet.py diff --git a/README_commandline.md b/README_commandline.md index 8965091a1..4bce92a8c 100644 --- a/README_commandline.md +++ b/README_commandline.md @@ -144,6 +144,15 @@ To list the domains referenced in public posts: python3 epicyon.py --postDomains nickname@domain ``` +## Plotting federated instances + +To plot a set of federated instances, based upon a sample of handles on those instances: + +``` bash +python3 epicyon.py --socnet nickname1@domain1,nickname2@domain2,nickname3@domain3 +xdot socnet.dot +``` + ## Delete posts To delete a post which you wrote you must first know its url. It is usually something like: diff --git a/epicyon.py b/epicyon.py index ef4d539bf..791c1e1cf 100644 --- a/epicyon.py +++ b/epicyon.py @@ -67,6 +67,7 @@ from shares import sendUndoShareViaServer from shares import addShare from theme import setTheme from announce import sendAnnounceViaServer +from socnet import instancesGraph import argparse @@ -151,6 +152,10 @@ parser.add_argument('--postDomains', dest='postDomains', type=str, default=None, help='Show domains referenced in public ' 'posts for the given handle') +parser.add_argument('--socnet', dest='socnet', type=str, + default=None, + help='Show dot diagram for social network ' + 'of federated instances') parser.add_argument('--postsraw', dest='postsraw', type=str, default=None, help='Show raw json of posts for the given handle') @@ -449,13 +454,35 @@ if args.postDomains: elif args.gnunet: proxyType = 'gnunet' domainList = [] - domainList = getPublicPostDomains(baseDir, nickname, domain, False, True, - proxyType, args.port, httpPrefix, debug, + domainList = getPublicPostDomains(baseDir, nickname, domain, + proxyType, args.port, + httpPrefix, debug, __version__, domainList) for postDomain in domainList: print(postDomain) sys.exit() +if args.socnet: + if ',' not in args.socnet: + print('Syntax: ' + '--socnet nick1@domain1,nick2@domain2,nick3@domain3') + sys.exit() + + if not args.http: + args.port = 443 + proxyType = 'tor' + dotGraph = instancesGraph(baseDir, args.socnet, + proxyType, args.port, + httpPrefix, debug, + __version__) + try: + with open('socnet.dot', 'w') as fp: + fp.write(dotGraph) + print('Saved to socnet.dot') + except BaseException: + pass + sys.exit() + if args.postsraw: if '@' not in args.postsraw: print('Syntax: --postsraw nickname@domain') diff --git a/posts.py b/posts.py index 1ed3541b5..830e2351f 100644 --- a/posts.py +++ b/posts.py @@ -146,11 +146,14 @@ def getUserUrl(wfRequest: {}) -> str: def parseUserFeed(session, feedUrl: str, asHeader: {}, projectVersion: str, httpPrefix: str, - domain: str) -> None: + domain: str,depth=0) -> {}: + if depth > 10: + return None + feedJson = getJson(session, feedUrl, asHeader, None, projectVersion, httpPrefix, domain) if not feedJson: - return + return None if 'orderedItems' in feedJson: for item in feedJson['orderedItems']: @@ -168,9 +171,10 @@ def parseUserFeed(session, feedUrl: str, asHeader: {}, userFeed = \ parseUserFeed(session, nextUrl, asHeader, projectVersion, httpPrefix, - domain) - for item in userFeed: - yield item + domain, depth+1) + if userFeed: + for item in userFeed: + yield item elif isinstance(nextUrl, dict): userFeed = nextUrl if userFeed.get('orderedItems'): @@ -444,8 +448,8 @@ def getPostDomains(session, outboxUrl: str, maxPosts: int, maxMentions: int, maxEmoji: int, maxAttachments: int, federationList: [], - personCache: {}, raw: bool, - simple: bool, debug: bool, + personCache: {}, + debug: bool, projectVersion: str, httpPrefix: str, domain: str, domainList=[]) -> []: """Returns a list of domains referenced within public posts @@ -467,6 +471,9 @@ def getPostDomains(session, outboxUrl: str, maxPosts: int, userFeed = parseUserFeed(session, outboxUrl, asHeader, projectVersion, httpPrefix, domain) for item in userFeed: + i += 1 + if i > maxPosts: + break if not item.get('object'): continue if not isinstance(item['object'], dict): @@ -486,9 +493,6 @@ def getPostDomains(session, outboxUrl: str, maxPosts: int, getDomainFromActor(tagItem['href']) if postDomain not in postDomains: postDomains.append(postDomain) - i += 1 - if i == maxPosts: - break return postDomains @@ -2986,8 +2990,7 @@ def getPublicPostsOfPerson(baseDir: str, nickname: str, domain: str, def getPublicPostDomains(baseDir: str, nickname: str, domain: str, - raw: bool, simple: bool, proxyType: str, - port: int, httpPrefix: str, + proxyType: str, port: int, httpPrefix: str, debug: bool, projectVersion: str, domainList=[]) -> []: """ Returns a list of domains referenced within public posts @@ -3028,7 +3031,7 @@ def getPublicPostDomains(baseDir: str, nickname: str, domain: str, postDomains = \ getPostDomains(session, personUrl, 64, maxMentions, maxEmoji, maxAttachments, federationList, - personCache, raw, simple, debug, + personCache, debug, projectVersion, httpPrefix, domain, domainList) postDomains.sort() return postDomains diff --git a/socnet.py b/socnet.py new file mode 100644 index 000000000..fca13dc26 --- /dev/null +++ b/socnet.py @@ -0,0 +1,83 @@ +__filename__ = "socnet.py" +__author__ = "Bob Mottram" +__license__ = "AGPL3+" +__version__ = "1.1.0" +__maintainer__ = "Bob Mottram" +__email__ = "bob@freedombone.net" +__status__ = "Production" + +from session import createSession +from webfinger import webfingerHandle +from posts import getPersonBox +from posts import getPostDomains + + +def instancesGraph(baseDir: str, handles: str, + proxyType: str, + port: int, httpPrefix: str, + debug: bool, projectVersion: str) -> str: + """ Returns a dot graph of federating instances + based upon a few sample handles. + The handles argument should contain a comma separated list + of handles on different instances + """ + dotGraphStr = 'digraph instances {\n' + if ',' not in handles: + return dotGraphStr + '}\n' + session = createSession(proxyType) + if not session: + return dotGraphStr + '}\n' + + personCache = {} + cachedWebfingers = {} + federationList = [] + maxMentions = 99 + maxEmoji = 99 + maxAttachments = 5 + + personHandles = handles.split(',') + for handle in personHandles: + handle = handle.strip() + if handle.startswith('@'): + handle = handle[1:] + if '@' not in handle: + continue + + nickname = handle.split('@')[0] + domain = handle.split('@')[1] + + domainFull = domain + if port: + if port != 80 and port != 443: + if ':' not in domain: + domainFull = domain + ':' + str(port) + handle = httpPrefix + "://" + domainFull + "/@" + nickname + wfRequest = \ + webfingerHandle(session, handle, httpPrefix, + cachedWebfingers, + domain, projectVersion) + if not wfRequest: + return dotGraphStr + '}\n' + if not isinstance(wfRequest, dict): + print('Webfinger for ' + handle + ' did not return a dict. ' + + str(wfRequest)) + return dotGraphStr + '}\n' + + (personUrl, pubKeyId, pubKey, + personId, shaedInbox, + capabilityAcquisition, + avatarUrl, displayName) = getPersonBox(baseDir, session, wfRequest, + personCache, + projectVersion, httpPrefix, + nickname, domain, 'outbox') + postDomains = \ + getPostDomains(session, personUrl, 64, maxMentions, maxEmoji, + maxAttachments, federationList, + personCache, debug, + projectVersion, httpPrefix, domain, []) + postDomains.sort() + for fedDomain in postDomains: + dotLineStr = ' "' + domain + '" -> "' + fedDomain + '";\n' + if dotLineStr not in dotGraphStr: + dotGraphStr += dotLineStr + return dotGraphStr + '}\n' From 0de149799f6088917e979d70f1e1c380bf558737 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 14:23:23 +0100 Subject: [PATCH 17/44] Clear dot files --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 45ef03d96..789fdbf43 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ source: rm -f ../${APP}*.deb ../${APP}*.changes ../${APP}*.asc ../${APP}*.dsc cd .. && mv ${APP} ${APP}-${VERSION} && tar -zcvf ${APP}_${VERSION}.orig.tar.gz ${APP}-${VERSION}/ && mv ${APP}-${VERSION} ${APP} clean: - rm -f *.*~ *~ + rm -f *.*~ *~ *.dot rm -f orgs/*~ rm -f website/EN/*~ rm -f gemini/EN/*~ From 22ca09caefbbcb3f292ecb1e623eb6696a77e403 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 14:25:00 +0100 Subject: [PATCH 18/44] Tidying --- posts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posts.py b/posts.py index 830e2351f..8dd550806 100644 --- a/posts.py +++ b/posts.py @@ -146,7 +146,7 @@ def getUserUrl(wfRequest: {}) -> str: def parseUserFeed(session, feedUrl: str, asHeader: {}, projectVersion: str, httpPrefix: str, - domain: str,depth=0) -> {}: + domain: str, depth=0) -> {}: if depth > 10: return None From 6fbba9242715a77861f790a50040f6f4809747a5 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 15:28:08 +0100 Subject: [PATCH 19/44] Security audit script --- README.md | 15 +++++++++++++-- deploy/i2p | 4 ++-- deploy/onion | 4 ++-- gemini/EN/install.gmi | 2 +- security_audit | 2 ++ website/EN/index.html | 2 +- 6 files changed, 21 insertions(+), 8 deletions(-) create mode 100755 security_audit diff --git a/README.md b/README.md index 13ec8785a..51eea597e 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ On Arch/Parabola: sudo pacman -S tor python-pip python-pysocks python-pycryptodome \ imagemagick python-pillow python-requests \ perl-image-exiftool python-numpy python-dateutil \ - certbot flake8 + certbot flake8 bandit sudo pip3 install pyLD pyqrcode pypng ``` @@ -37,7 +37,8 @@ sudo apt install -y \ python3-idna python3-requests \ python3-pyld python3-django-timezone-field \ libimage-exiftool-perl python3-flake8 \ - python3-pyqrcode python3-png certbot nginx + python3-pyqrcode python3-png python3-bandit \ + certbot nginx ``` ## Installation @@ -196,6 +197,16 @@ Static analysis can be run with: ./static_analysis ``` +## Running a security audit + +To run a security audit: + +``` bash +./security_audit +``` + +Note that not all of the issues identified will necessarily be relevant to this project. + ## Installing on Onion or i2p domains If you don't have access to the clearnet, or prefer not to use it, then it's possible to run an Epicyon instance easily from your laptop. There are scripts within the ```deploy``` directory which can be used to install an instance on a Debian or Arch/Parabola operating system. With some modification of package names they could be also used with other distros. diff --git a/deploy/i2p b/deploy/i2p index d390d5500..2afeb74ab 100755 --- a/deploy/i2p +++ b/deploy/i2p @@ -64,7 +64,7 @@ if [ -f /usr/bin/pacman ]; then imagemagick python-pillow python-requests \ perl-image-exiftool python-numpy python-dateutil \ certbot flake8 git i2pd wget qrencode \ - proxychains midori + proxychains midori bandit pip3 install pyLD pyqrcode pypng else apt-get update @@ -75,7 +75,7 @@ else libimage-exiftool-perl python3-flake8 python3-pyld \ python3-django-timezone-field nginx git i2pd wget \ python3-pyqrcode qrencode python3-png \ - proxychains midori + proxychains midori python3-bandit fi if [ ! -d /etc/i2pd ]; then diff --git a/deploy/onion b/deploy/onion index 6c1093c04..c60df40b1 100755 --- a/deploy/onion +++ b/deploy/onion @@ -38,7 +38,7 @@ if [ -f /usr/bin/pacman ]; then pacman -S --noconfirm tor python-pip python-pysocks python-pycryptodome \ imagemagick python-pillow python-requests \ perl-image-exiftool python-numpy python-dateutil \ - certbot flake8 git qrencode + certbot flake8 git qrencode bandit pip3 install pyLD pyqrcode pypng else apt-get update @@ -48,7 +48,7 @@ else python3-setuptools python3-socks python3-idna \ libimage-exiftool-perl python3-flake8 python3-pyld \ python3-django-timezone-field tor nginx git qrencode \ - python3-pyqrcode python3-png + python3-pyqrcode python3-png python3-bandit fi echo 'Cloning the epicyon repo' diff --git a/gemini/EN/install.gmi b/gemini/EN/install.gmi index 6484b30fa..0eb54ba71 100644 --- a/gemini/EN/install.gmi +++ b/gemini/EN/install.gmi @@ -4,7 +4,7 @@ You will need python version 3.7 or later. On a Debian based system: - sudo apt install -y tor python3-socks imagemagick python3-numpy python3-setuptools python3-crypto python3-pycryptodome python3-dateutil python3-pil.imagetk python3-idna python3-requests python3-flake8 python3-pyld python3-django-timezone-field python3-pyqrcode python3-png libimage-exiftool-perl certbot nginx + sudo apt install -y tor python3-socks imagemagick python3-numpy python3-setuptools python3-crypto python3-pycryptodome python3-dateutil python3-pil.imagetk python3-idna python3-requests python3-flake8 python3-pyld python3-django-timezone-field python3-pyqrcode python3-png python3-bandit libimage-exiftool-perl certbot nginx The following instructions install Epicyon to the /opt directory. It's not essential that it be installed there, and it could be in any other preferred directory. diff --git a/security_audit b/security_audit new file mode 100755 index 000000000..5a47f8c46 --- /dev/null +++ b/security_audit @@ -0,0 +1,2 @@ +#!/bin/bash +bandit *.py -x tests.py \ No newline at end of file diff --git a/website/EN/index.html b/website/EN/index.html index 61afe827d..712b11ea1 100644 --- a/website/EN/index.html +++ b/website/EN/index.html @@ -1264,7 +1264,7 @@

You will need python version 3.7 or later.

On a Debian based system:

-

sudo apt install -y tor python3-socks imagemagick python3-numpy python3-setuptools python3-crypto python3-pycryptodome python3-dateutil python3-pil.imagetk python3-idna python3-requests python3-flake8 python3-pyld python3-django-timezone-field python3-pyqrcode python3-png libimage-exiftool-perl certbot nginx

+

sudo apt install -y tor python3-socks imagemagick python3-numpy python3-setuptools python3-crypto python3-pycryptodome python3-dateutil python3-pil.imagetk python3-idna python3-requests python3-flake8 python3-pyld python3-django-timezone-field python3-pyqrcode python3-png python3-bandit libimage-exiftool-perl certbot nginx

From 48553013f6eca6c51a24e6f2e68b3ed5402a5bdf Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 15:32:11 +0100 Subject: [PATCH 20/44] Check that file gets copied --- media.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/media.py b/media.py index fd372b760..e811fe60e 100644 --- a/media.py +++ b/media.py @@ -38,12 +38,15 @@ def removeMetaData(imageFilename: str, outputFilename: str) -> None: so better to use a dedicated tool if one is installed """ copyfile(imageFilename, outputFilename) + if not os.path.isfile(outputFilename): + print('ERROR: unable to remove metadata from ' + imageFilename) + return if os.path.isfile('/usr/bin/exiftool'): print('Removing metadata from ' + outputFilename + ' using exiftool') os.system('exiftool -all= ' + outputFilename) elif os.path.isfile('/usr/bin/mogrify'): print('Removing metadata from ' + outputFilename + ' using mogrify') - os.system('/usr/bin/mogrify -strip '+outputFilename) + os.system('/usr/bin/mogrify -strip ' + outputFilename) def getImageHash(imageFilename: str) -> str: From b02ddbaed0b3601ea388cddaad8d39a9b8003f97 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 16:09:27 +0100 Subject: [PATCH 21/44] Use secrets for password generation --- auth.py | 3 ++- daemon.py | 4 ++-- media.py | 6 +++--- person.py | 15 +++++++++++---- utils.py | 12 ++++++++---- 5 files changed, 26 insertions(+), 14 deletions(-) diff --git a/auth.py b/auth.py index 8f162e429..9fad6de20 100644 --- a/auth.py +++ b/auth.py @@ -11,6 +11,7 @@ import hashlib import binascii import os import random +import secrets def hashPassword(password: str) -> str: @@ -162,4 +163,4 @@ def authorize(baseDir: str, path: str, authHeader: str, debug: bool) -> bool: def createPassword(length=10): validChars = 'abcdefghijklmnopqrstuvwxyz' + \ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' - return ''.join((random.choice(validChars) for i in range(length))) + return ''.join((secrets.choice(validChars) for i in range(length))) diff --git a/daemon.py b/daemon.py index 53a9ae6a0..b24a0ddc7 100644 --- a/daemon.py +++ b/daemon.py @@ -535,7 +535,7 @@ class PubServer(BaseHTTPRequestHandler): except BaseException: pass if not etag: - etag = sha1(data).hexdigest() + etag = sha1(data).hexdigest() # nosec try: with open(mediaFilename + '.etag', 'w') as etagFile: etagFile.write(etag) @@ -5098,7 +5098,7 @@ class PubServer(BaseHTTPRequestHandler): else: with open(mediaFilename, 'rb') as avFile: mediaBinary = avFile.read() - etag = sha1(mediaBinary).hexdigest() + etag = sha1(mediaBinary).hexdigest() # nosec try: with open(mediaTagFilename, 'w') as etagFile: etagFile.write(etag) diff --git a/media.py b/media.py index e811fe60e..dcc6ca9e5 100644 --- a/media.py +++ b/media.py @@ -43,10 +43,10 @@ def removeMetaData(imageFilename: str, outputFilename: str) -> None: return if os.path.isfile('/usr/bin/exiftool'): print('Removing metadata from ' + outputFilename + ' using exiftool') - os.system('exiftool -all= ' + outputFilename) + os.system('exiftool -all= ' + outputFilename) # nosec elif os.path.isfile('/usr/bin/mogrify'): print('Removing metadata from ' + outputFilename + ' using mogrify') - os.system('/usr/bin/mogrify -strip ' + outputFilename) + os.system('/usr/bin/mogrify -strip ' + outputFilename) # nosec def getImageHash(imageFilename: str) -> str: @@ -119,7 +119,7 @@ def updateEtag(mediaFilename: str) -> None: if not data: return # calculate hash - etag = sha1(data).hexdigest() + etag = sha1(data).hexdigest() # nosec # save the hash try: with open(mediaFilename + '.etag', 'w') as etagFile: diff --git a/person.py b/person.py index 3db66c57b..eab69cd8b 100644 --- a/person.py +++ b/person.py @@ -151,13 +151,17 @@ def randomizeActorImages(personJson: {}) -> None: personId = personJson['id'] lastPartOfFilename = personJson['icon']['url'].split('/')[-1] existingExtension = lastPartOfFilename.split('.')[1] + # NOTE: these files don't need to have cryptographically + # secure names personJson['icon']['url'] = \ - personId + '/avatar' + str(randint(10000000000000, 99999999999999)) + \ + personId + '/avatar' + \ + str(randint(10000000000000, 99999999999999)) + \ # nosec '.' + existingExtension lastPartOfFilename = personJson['image']['url'].split('/')[-1] existingExtension = lastPartOfFilename.split('.')[1] personJson['image']['url'] = \ - personId + '/image' + str(randint(10000000000000, 99999999999999)) + \ + personId + '/image' + \ + str(randint(10000000000000, 99999999999999)) + \ # nosec '.' + existingExtension @@ -197,13 +201,16 @@ def createPersonBase(baseDir: str, nickname: str, domain: str, port: int, approveFollowers = True personType = 'Application' + # NOTE: these image files don't need to have + # cryptographically secure names + imageUrl = \ personId + '/image' + \ - str(randint(10000000000000, 99999999999999)) + '.png' + str(randint(10000000000000, 99999999999999)) + '.png' # nosec iconUrl = \ personId + '/avatar' + \ - str(randint(10000000000000, 99999999999999)) + '.png' + str(randint(10000000000000, 99999999999999)) + '.png' # nosec contextDict = { 'Emoji': 'toot:Emoji', diff --git a/utils.py b/utils.py index cf8ad07d5..69a882f48 100644 --- a/utils.py +++ b/utils.py @@ -13,7 +13,7 @@ import datetime import json from socket import error as SocketError import errno -from urllib.request import urlopen +import urllib.request from pprint import pprint from calendar import monthrange from followingCalendar import addPersonToCalendar @@ -1095,10 +1095,14 @@ def siteIsActive(url: str) -> bool: This can be used to check that an instance is online before trying to send posts to it. """ + if not url.startswith('http'): + return False try: - urlopen(url, timeout=10) - return True + req = urllib.request.Request(url) + with urllib.request.urlopen(req, timeout=10) as res: # nosec + # testStr = response.read() + return True except SocketError as e: if e.errno == errno.ECONNRESET: print('WARN: connection was reset during siteIsActive') - return False + return False From db64ceb87df7c5331c7a304c7c44e9a6db64de34 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 16:17:00 +0100 Subject: [PATCH 22/44] Tidying --- auth.py | 1 - daemon.py | 4 ++-- media.py | 6 +++--- person.py | 14 ++++++-------- utils.py | 5 ++--- 5 files changed, 13 insertions(+), 17 deletions(-) diff --git a/auth.py b/auth.py index 9fad6de20..8297aa816 100644 --- a/auth.py +++ b/auth.py @@ -10,7 +10,6 @@ import base64 import hashlib import binascii import os -import random import secrets diff --git a/daemon.py b/daemon.py index b24a0ddc7..9007ed3b6 100644 --- a/daemon.py +++ b/daemon.py @@ -535,7 +535,7 @@ class PubServer(BaseHTTPRequestHandler): except BaseException: pass if not etag: - etag = sha1(data).hexdigest() # nosec + etag = sha1(data).hexdigest() # nosec try: with open(mediaFilename + '.etag', 'w') as etagFile: etagFile.write(etag) @@ -5098,7 +5098,7 @@ class PubServer(BaseHTTPRequestHandler): else: with open(mediaFilename, 'rb') as avFile: mediaBinary = avFile.read() - etag = sha1(mediaBinary).hexdigest() # nosec + etag = sha1(mediaBinary).hexdigest() # nosec try: with open(mediaTagFilename, 'w') as etagFile: etagFile.write(etag) diff --git a/media.py b/media.py index dcc6ca9e5..4afa96571 100644 --- a/media.py +++ b/media.py @@ -43,10 +43,10 @@ def removeMetaData(imageFilename: str, outputFilename: str) -> None: return if os.path.isfile('/usr/bin/exiftool'): print('Removing metadata from ' + outputFilename + ' using exiftool') - os.system('exiftool -all= ' + outputFilename) # nosec + os.system('exiftool -all= ' + outputFilename) # nosec elif os.path.isfile('/usr/bin/mogrify'): print('Removing metadata from ' + outputFilename + ' using mogrify') - os.system('/usr/bin/mogrify -strip ' + outputFilename) # nosec + os.system('/usr/bin/mogrify -strip ' + outputFilename) # nosec def getImageHash(imageFilename: str) -> str: @@ -119,7 +119,7 @@ def updateEtag(mediaFilename: str) -> None: if not data: return # calculate hash - etag = sha1(data).hexdigest() # nosec + etag = sha1(data).hexdigest() # nosec # save the hash try: with open(mediaFilename + '.etag', 'w') as etagFile: diff --git a/person.py b/person.py index eab69cd8b..2196b68b3 100644 --- a/person.py +++ b/person.py @@ -153,16 +153,14 @@ def randomizeActorImages(personJson: {}) -> None: existingExtension = lastPartOfFilename.split('.')[1] # NOTE: these files don't need to have cryptographically # secure names + randStr = str(randint(10000000000000, 99999999999999)) # nosec personJson['icon']['url'] = \ - personId + '/avatar' + \ - str(randint(10000000000000, 99999999999999)) + \ # nosec - '.' + existingExtension + personId + '/avatar' + randStr + '.' + existingExtension lastPartOfFilename = personJson['image']['url'].split('/')[-1] existingExtension = lastPartOfFilename.split('.')[1] + randStr = str(randint(10000000000000, 99999999999999)) # nosec personJson['image']['url'] = \ - personId + '/image' + \ - str(randint(10000000000000, 99999999999999)) + \ # nosec - '.' + existingExtension + personId + '/image' + randStr + '.' + existingExtension def createPersonBase(baseDir: str, nickname: str, domain: str, port: int, @@ -206,11 +204,11 @@ def createPersonBase(baseDir: str, nickname: str, domain: str, port: int, imageUrl = \ personId + '/image' + \ - str(randint(10000000000000, 99999999999999)) + '.png' # nosec + str(randint(10000000000000, 99999999999999)) + '.png' # nosec iconUrl = \ personId + '/avatar' + \ - str(randint(10000000000000, 99999999999999)) + '.png' # nosec + str(randint(10000000000000, 99999999999999)) + '.png' # nosec contextDict = { 'Emoji': 'toot:Emoji', diff --git a/utils.py b/utils.py index 69a882f48..c53811f26 100644 --- a/utils.py +++ b/utils.py @@ -1099,9 +1099,8 @@ def siteIsActive(url: str) -> bool: return False try: req = urllib.request.Request(url) - with urllib.request.urlopen(req, timeout=10) as res: # nosec - # testStr = response.read() - return True + urllib.request.urlopen(req, timeout=10) # nosec + return True except SocketError as e: if e.errno == errno.ECONNRESET: print('WARN: connection was reset during siteIsActive') From 31e40671a953336acccd61bf648ccad61488a28e Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 16:21:04 +0100 Subject: [PATCH 23/44] Remove debug --- tests.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests.py b/tests.py index ba21720bc..55b0f7583 100644 --- a/tests.py +++ b/tests.py @@ -1879,7 +1879,6 @@ def testRemoveHtml(): testStr = 'This string has no html.' assert(removeHtml(testStr) == testStr) testStr = 'This string has html.' - print(removeHtml(testStr)) assert(removeHtml(testStr) == 'This string has html.') From a5e32811d4ee6bc98ccdab2a61899b1f2beaddd3 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 18:39:40 +0100 Subject: [PATCH 24/44] Show number of likes in title --- webinterface.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/webinterface.py b/webinterface.py index dad767950..7a5065156 100644 --- a/webinterface.py +++ b/webinterface.py @@ -3816,7 +3816,11 @@ def individualPostAsHtml(recentPostsCache: {}, maxRecentPosts: int, likeIcon = 'like_inactive.png' likeLink = 'like' likeTitle = translate['Like this post'] - if noOfLikes(postJsonObject) > 0: + likeCount = noOfLikes(postJsonObject) + likeCountStr = '' + if likeCount > 0: + if likeCount > 1: + likeCountStr = ' (' + str(likeCount) + ')' likeIcon = 'like.png' if likedByPerson(postJsonObject, nickname, fullDomain): likeLink = 'unlike' @@ -3827,9 +3831,10 @@ def individualPostAsHtml(recentPostsCache: {}, maxRecentPosts: int, pageNumberParam + \ '?actor=' + postJsonObject['actor'] + \ '?bm=' + timelinePostBookmark + \ - '?tl=' + boxName + '" title="' + likeTitle + '">' + '?tl=' + boxName + '" title="' + \ + likeTitle + likeCountStr + '">' likeStr += \ - '' + likeTitle + \
             ' |' From 4c09983932c01afcc0e60edda6e8dc626731e098 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 18:45:54 +0100 Subject: [PATCH 25/44] Avoid showing large numbers of likes --- webinterface.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/webinterface.py b/webinterface.py index 7a5065156..c14bd634a 100644 --- a/webinterface.py +++ b/webinterface.py @@ -3820,7 +3820,10 @@ def individualPostAsHtml(recentPostsCache: {}, maxRecentPosts: int, likeCountStr = '' if likeCount > 0: if likeCount > 1: - likeCountStr = ' (' + str(likeCount) + ')' + if likeCount <= 10: + likeCountStr = ' (' + str(likeCount) + ')' + else: + likeCountStr = ' (10+)' likeIcon = 'like.png' if likedByPerson(postJsonObject, nickname, fullDomain): likeLink = 'unlike' From 61f7a096703d97d4e5b1f6b77326020e8b435956 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 20:49:15 +0100 Subject: [PATCH 26/44] Create notification when likes arrive --- inbox.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/inbox.py b/inbox.py index 56c3b5f80..237fa98bb 100644 --- a/inbox.py +++ b/inbox.py @@ -1033,6 +1033,7 @@ def receiveLike(recentPostsCache: {}, updateLikesCollection(recentPostsCache, baseDir, postFilename, messageJson['object'], messageJson['actor'], domain, debug) + likeNotify(baseDir, handle, messageJson['actor'], messageJson['object']) return True @@ -1704,6 +1705,28 @@ def dmNotify(baseDir: str, handle: str, url: str) -> None: fp.write(url) +def likeNotify(baseDir: str, handle: str, actor: str, url: str) -> None: + """Creates a notification that a like has arrived + """ + accountDir = baseDir + '/accounts/' + handle + if not os.path.isdir(accountDir): + return + likeFile = accountDir + '/.newLike' + + domain = handle.split('@')[1] + nickname = handle.split('@')[0] + actor = '://' + domain + '/users/' + nickname + # the liked post is one which you made + if actor not in url: + return + likerNickname = getNicknameFromActor(actor) + likerDomain, likerPort = getDomainFromActor(actor) + likerHandle = likerNickname + '@' + likerDomain + if likerHandle != handle: + with open(likeFile, 'w') as fp: + fp.write(likerHandle + ' ' + url) + + def replyNotify(baseDir: str, handle: str, url: str) -> None: """Creates a notification that a new reply has arrived """ From 451714e280f253a8977151feba569bc9487855a5 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 21:28:54 +0100 Subject: [PATCH 27/44] Likes notification --- epicyon-notification | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/epicyon-notification b/epicyon-notification index 1c79d748b..1d3d5a8ec 100755 --- a/epicyon-notification +++ b/epicyon-notification @@ -177,6 +177,21 @@ function notifications { fi fi + # send notifications for likes to XMPP/email users + epicyonLikeFile="$epicyonDir/.newLike" + if [ -f "$epicyonLikeFile" ]; then + if ! grep -q "##sent##" "$epicyonLikeFile"; then + epicyonLikeMessage=$(notification_translate_text 'liked your post') + epicyonLikeFileContent=$(cat "$epicyonLikeFile" | awk -F ' ' '{print $1}')" "$(echo "$epicyonLikeMessage")" "$(cat "$epicyonLikeFile" | awk -F ' ' '{print $2}') + if [[ "$epicyonLikeFileContent" == *':'* ]]; then + epicyonLikeMessage="Epicyon: $epicyonLikeFileContent" + fi + "${PROJECT_NAME}-notification" -u "$USERNAME" -s "Epicyon" -m "$epicyonLikeMessage" --sensitive yes + echo "##sent##" > "$epicyonLikeFile" + chown ${PROJECT_NAME}:${PROJECT_NAME} "$epicyonLkeFile" + fi + fi + # send notifications for replies to XMPP/email users epicyonReplyFile="$epicyonDir/.newReply" if [ -f "$epicyonReplyFile" ]; then From 290ea18b0b1588a419a6c19d2c8c919e01d05eac Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 22:04:19 +0100 Subject: [PATCH 28/44] Check nickname and domain --- inbox.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/inbox.py b/inbox.py index 237fa98bb..e05e8abb2 100644 --- a/inbox.py +++ b/inbox.py @@ -1719,9 +1719,15 @@ def likeNotify(baseDir: str, handle: str, actor: str, url: str) -> None: # the liked post is one which you made if actor not in url: return + likerNickname = None + likerDomain = None likerNickname = getNicknameFromActor(actor) likerDomain, likerPort = getDomainFromActor(actor) - likerHandle = likerNickname + '@' + likerDomain + if likerNickname and likerDomain: + likerHandle = likerNickname + '@' + likerDomain + else: + print('likeNotify actor: ' + str(actor)) + likerHandle = actor if likerHandle != handle: with open(likeFile, 'w') as fp: fp.write(likerHandle + ' ' + url) From 10ae18affcb84d20f9adfc220117aa249dc4184b Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 22:18:50 +0100 Subject: [PATCH 29/44] Debug --- inbox.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/inbox.py b/inbox.py index e05e8abb2..509b96fe1 100644 --- a/inbox.py +++ b/inbox.py @@ -1033,7 +1033,9 @@ def receiveLike(recentPostsCache: {}, updateLikesCollection(recentPostsCache, baseDir, postFilename, messageJson['object'], messageJson['actor'], domain, debug) - likeNotify(baseDir, handle, messageJson['actor'], messageJson['object']) + print('likeNotify: ' + str(messageJson)) + likeNotify(baseDir, handle, + messageJson['actor'], messageJson['object'], httpPrefix) return True @@ -1705,7 +1707,8 @@ def dmNotify(baseDir: str, handle: str, url: str) -> None: fp.write(url) -def likeNotify(baseDir: str, handle: str, actor: str, url: str) -> None: +def likeNotify(baseDir: str, handle: str, actor: str, url: str, + httpPrefix: str) -> None: """Creates a notification that a like has arrived """ accountDir = baseDir + '/accounts/' + handle @@ -1715,18 +1718,17 @@ def likeNotify(baseDir: str, handle: str, actor: str, url: str) -> None: domain = handle.split('@')[1] nickname = handle.split('@')[0] - actor = '://' + domain + '/users/' + nickname + actor = httpPrefix + '://' + domain + '/users/' + nickname # the liked post is one which you made if actor not in url: return - likerNickname = None - likerDomain = None likerNickname = getNicknameFromActor(actor) likerDomain, likerPort = getDomainFromActor(actor) if likerNickname and likerDomain: likerHandle = likerNickname + '@' + likerDomain else: - print('likeNotify actor: ' + str(actor)) + print('likeNotify likerHandle: ' + + str(likerNickname) + '@' + str(likerDomain)) likerHandle = actor if likerHandle != handle: with open(likeFile, 'w') as fp: From 3607bfd439688ee7547261cd0094a577e31200f5 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 22:28:44 +0100 Subject: [PATCH 30/44] Check for liking own post --- inbox.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/inbox.py b/inbox.py index 509b96fe1..72a5393f6 100644 --- a/inbox.py +++ b/inbox.py @@ -1716,11 +1716,8 @@ def likeNotify(baseDir: str, handle: str, actor: str, url: str, return likeFile = accountDir + '/.newLike' - domain = handle.split('@')[1] - nickname = handle.split('@')[0] - actor = httpPrefix + '://' + domain + '/users/' + nickname - # the liked post is one which you made - if actor not in url: + # This is not you liking your own post + if actor in url: return likerNickname = getNicknameFromActor(actor) likerDomain, likerPort = getDomainFromActor(actor) From 81c06ae2f52592d578a6b47421f2f872a121fe9b Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 22:34:54 +0100 Subject: [PATCH 31/44] Tidying --- inbox.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/inbox.py b/inbox.py index 72a5393f6..fe61de1ca 100644 --- a/inbox.py +++ b/inbox.py @@ -1035,7 +1035,7 @@ def receiveLike(recentPostsCache: {}, messageJson['actor'], domain, debug) print('likeNotify: ' + str(messageJson)) likeNotify(baseDir, handle, - messageJson['actor'], messageJson['object'], httpPrefix) + messageJson['actor'], messageJson['object']) return True @@ -1707,8 +1707,7 @@ def dmNotify(baseDir: str, handle: str, url: str) -> None: fp.write(url) -def likeNotify(baseDir: str, handle: str, actor: str, url: str, - httpPrefix: str) -> None: +def likeNotify(baseDir: str, handle: str, actor: str, url: str) -> None: """Creates a notification that a like has arrived """ accountDir = baseDir + '/accounts/' + handle From 80248889b880c2b8f4aaaa66e0e5db395cd9b42c Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 22:37:03 +0100 Subject: [PATCH 32/44] Remove debug --- inbox.py | 1 - 1 file changed, 1 deletion(-) diff --git a/inbox.py b/inbox.py index fe61de1ca..1b1535e33 100644 --- a/inbox.py +++ b/inbox.py @@ -1033,7 +1033,6 @@ def receiveLike(recentPostsCache: {}, updateLikesCollection(recentPostsCache, baseDir, postFilename, messageJson['object'], messageJson['actor'], domain, debug) - print('likeNotify: ' + str(messageJson)) likeNotify(baseDir, handle, messageJson['actor'], messageJson['object']) return True From 57d64ed033834d8a76e49aa37aca703d677718aa Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 22:41:48 +0100 Subject: [PATCH 33/44] Check if like notification exists --- inbox.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/inbox.py b/inbox.py index 1b1535e33..c0c05f49a 100644 --- a/inbox.py +++ b/inbox.py @@ -1713,6 +1713,8 @@ def likeNotify(baseDir: str, handle: str, actor: str, url: str) -> None: if not os.path.isdir(accountDir): return likeFile = accountDir + '/.newLike' + if os.path.isfile(likeFile): + return # This is not you liking your own post if actor in url: From cfba4874f8676a2f28ee254461359957ad19db71 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 22:52:18 +0100 Subject: [PATCH 34/44] Check for sent like notifications --- inbox.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/inbox.py b/inbox.py index c0c05f49a..81ebda565 100644 --- a/inbox.py +++ b/inbox.py @@ -1714,7 +1714,8 @@ def likeNotify(baseDir: str, handle: str, actor: str, url: str) -> None: return likeFile = accountDir + '/.newLike' if os.path.isfile(likeFile): - return + if '##sent##' not in open(likeFile).read(): + return # This is not you liking your own post if actor in url: From a70edfab53c75d68d885a2d5ea5549f092b96f84 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 23:04:17 +0100 Subject: [PATCH 35/44] Check that the liked post is by this handle --- inbox.py | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/inbox.py b/inbox.py index 81ebda565..3c93ca788 100644 --- a/inbox.py +++ b/inbox.py @@ -981,6 +981,7 @@ def receiveUpdate(recentPostsCache: {}, session, baseDir: str, def receiveLike(recentPostsCache: {}, session, handle: str, isGroup: bool, baseDir: str, httpPrefix: str, domain: str, port: int, + onionDomain: str, sendThreads: [], postLog: [], cachedWebfingers: {}, personCache: {}, messageJson: {}, federationList: [], debug: bool) -> bool: @@ -1033,7 +1034,7 @@ def receiveLike(recentPostsCache: {}, updateLikesCollection(recentPostsCache, baseDir, postFilename, messageJson['object'], messageJson['actor'], domain, debug) - likeNotify(baseDir, handle, + likeNotify(baseDir, domain, onionDomain, handle, messageJson['actor'], messageJson['object']) return True @@ -1706,9 +1707,22 @@ def dmNotify(baseDir: str, handle: str, url: str) -> None: fp.write(url) -def likeNotify(baseDir: str, handle: str, actor: str, url: str) -> None: +def likeNotify(baseDir: str, domain: str, onionDomain: str, + handle: str, actor: str, url: str) -> None: """Creates a notification that a like has arrived """ + # This is not you liking your own post + if actor in url: + return + + # check that the liked post was by this handle + nickname = handle.split('@')[0] + if '/' + domain + '/users/' + nickname not in url: + if not onionDomain: + return + if '/' + onionDomain + '/users/' + nickname not in url: + return + accountDir = baseDir + '/accounts/' + handle if not os.path.isdir(accountDir): return @@ -1717,9 +1731,6 @@ def likeNotify(baseDir: str, handle: str, actor: str, url: str) -> None: if '##sent##' not in open(likeFile).read(): return - # This is not you liking your own post - if actor in url: - return likerNickname = getNicknameFromActor(actor) likerDomain, likerPort = getDomainFromActor(actor) if likerNickname and likerDomain: @@ -1999,6 +2010,7 @@ def inboxAfterCapabilities(recentPostsCache: {}, maxRecentPosts: int, session, handle, isGroup, baseDir, httpPrefix, domain, port, + onionDomain, sendThreads, postLog, cachedWebfingers, personCache, From ac0dd52c78a878a747f55f73dcd6796324de89fd Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 8 Jul 2020 23:17:21 +0100 Subject: [PATCH 36/44] Check for repeated like notifications --- inbox.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/inbox.py b/inbox.py index 3c93ca788..5164365a5 100644 --- a/inbox.py +++ b/inbox.py @@ -1740,8 +1740,19 @@ def likeNotify(baseDir: str, domain: str, onionDomain: str, str(likerNickname) + '@' + str(likerDomain)) likerHandle = actor if likerHandle != handle: + likeStr = likerHandle + ' ' + url + prevLikeFile = accountDir + '/.prevLike' + # was there a previous like notification? + if os.path.isfile(prevLikeFile): + # is it the same as the current notification ? + with open(prevLikeFile, 'r') as likeFile: + prevLikeStr = likeFile.read() + if prevLikeStr == likeStr: + return + with open(prevLikeFile, 'w') as fp: + fp.write(likeStr) with open(likeFile, 'w') as fp: - fp.write(likerHandle + ' ' + url) + fp.write(likeStr) def replyNotify(baseDir: str, handle: str, url: str) -> None: From 1a15d07dfd1afffeb2a652369ec342bb606475a6 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Fri, 10 Jul 2020 14:15:01 +0000 Subject: [PATCH 37/44] Improve checking for bad markup --- content.py | 26 ++++++++++++++++++++++++++ inbox.py | 21 ++++++++++----------- tests.py | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 11 deletions(-) diff --git a/content.py b/content.py index 1df206fdd..b7952ace6 100644 --- a/content.py +++ b/content.py @@ -14,6 +14,32 @@ from utils import fileLastModified from utils import getLinkPrefixes +def dangerousMarkup(content: str) -> bool: + """Returns true if the given content contains dangerous html markup + """ + if '<' not in content: + return False + if '>' not in content: + return False + contentSections = content.split('<') + invalidStrings = ('script', 'canvas', 'style', 'abbr', + 'frame', 'iframe', 'html', 'body', + 'hr', 'br') + for markup in contentSections: + if '>' not in markup: + continue + markup = markup.split('>')[0].strip() + if ' ' not in markup: + for badStr in invalidStrings: + if badStr in markup: + return True + else: + for badStr in invalidStrings: + if badStr + ' ' in markup: + return True + return False + + def switchWords(baseDir: str, nickname: str, domain: str, content: str) -> str: """Performs word replacements. eg. Trump -> The Orange Menace """ diff --git a/inbox.py b/inbox.py index 5164365a5..20496828e 100644 --- a/inbox.py +++ b/inbox.py @@ -63,6 +63,7 @@ from media import replaceYouTube from git import isGitPatch from git import receiveGitPatch from followingCalendar import receivingCalendarEvents +from content import dangerousMarkup def storeHashTags(baseDir: str, nickname: str, postJsonObject: {}) -> None: @@ -1599,22 +1600,20 @@ def validPostContent(baseDir: str, nickname: str, domain: str, return False if 'Z' not in messageJson['object']['published']: return False + if isGitPatch(baseDir, nickname, domain, messageJson['object']['type'], messageJson['object']['summary'], messageJson['object']['content']): return True - # check for bad html - invalidStrings = ('', '', - '', '', - '', '', '
', '


') - for badStr in invalidStrings: - if badStr in messageJson['object']['content']: - if messageJson['object'].get('id'): - print('REJECT ARBITRARY HTML: ' + messageJson['object']['id']) - print('REJECT ARBITRARY HTML: bad string in post - ' + - messageJson['object']['content']) - return False + + if dangerousMarkup(messageJson['object']['content']): + if messageJson['object'].get('id'): + print('REJECT ARBITRARY HTML: ' + messageJson['object']['id']) + print('REJECT ARBITRARY HTML: bad string in post - ' + + messageJson['object']['content']) + return False + # check (rough) number of mentions mentionsEst = estimateNumberOfMentions(messageJson['object']['content']) if mentionsEst > maxMentions: diff --git a/tests.py b/tests.py index 55b0f7583..12faa4634 100644 --- a/tests.py +++ b/tests.py @@ -64,6 +64,7 @@ from media import getAttachmentMediaType from delete import sendDeleteViaServer from inbox import validInbox from inbox import validInboxFilenames +from content import dangerousMarkup from content import removeHtml from content import addWebLinks from content import replaceEmojiFromTags @@ -1882,8 +1883,40 @@ def testRemoveHtml(): assert(removeHtml(testStr) == 'This string has html.') +def testDangerousMarkup(): + print('testDangerousMarkup') + content = '

This is a valid message

' + assert(not dangerousMarkup(content)) + content = 'This is a valid message without markup' + assert(not dangerousMarkup(content)) + content = '

This is a valid-looking message. But wait... ' + \ + '

' + assert(dangerousMarkup(content)) + content = '

This is a valid-looking message. But wait... ' + \ + '