| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  | __filename__ = "daemon.py" | 
					
						
							|  |  |  | __author__ = "Bob Mottram" | 
					
						
							|  |  |  | __license__ = "AGPL3+" | 
					
						
							| 
									
										
										
										
											2019-08-29 13:35:29 +00:00
										 |  |  | __version__ = "1.0.0" | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  | __maintainer__ = "Bob Mottram" | 
					
						
							|  |  |  | __email__ = "bob@freedombone.net" | 
					
						
							|  |  |  | __status__ = "Production" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-15 12:01:56 +00:00
										 |  |  | from http.server import BaseHTTPRequestHandler,ThreadingHTTPServer | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  | #import socketserver | 
					
						
							| 
									
										
										
										
											2019-07-06 21:24:47 +00:00
										 |  |  | import commentjson | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  | import json | 
					
						
							| 
									
										
										
										
											2019-07-01 14:30:48 +00:00
										 |  |  | import time | 
					
						
							| 
									
										
										
										
											2019-07-27 20:30:58 +00:00
										 |  |  | import base64 | 
					
						
							|  |  |  | # used for mime decoding of message POST | 
					
						
							|  |  |  | import email.parser | 
					
						
							|  |  |  | # for saving images | 
					
						
							|  |  |  | from binascii import a2b_base64 | 
					
						
							| 
									
										
										
										
											2019-07-25 14:24:42 +00:00
										 |  |  | from hashlib import sha256 | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  | from pprint import pprint | 
					
						
							|  |  |  | from session import createSession | 
					
						
							|  |  |  | from webfinger import webfingerMeta | 
					
						
							|  |  |  | from webfinger import webfingerLookup | 
					
						
							| 
									
										
										
										
											2019-07-01 21:01:43 +00:00
										 |  |  | from webfinger import webfingerHandle | 
					
						
							| 
									
										
										
										
											2019-08-08 13:38:33 +00:00
										 |  |  | from person import registerAccount | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  | from person import personLookup | 
					
						
							| 
									
										
										
										
											2019-07-04 16:24:23 +00:00
										 |  |  | from person import personBoxJson | 
					
						
							| 
									
										
										
										
											2019-07-11 12:29:31 +00:00
										 |  |  | from person import createSharedInbox | 
					
						
							| 
									
										
										
										
											2019-08-13 09:24:55 +00:00
										 |  |  | from person import isSuspended | 
					
						
							| 
									
										
										
										
											2019-08-13 11:59:38 +00:00
										 |  |  | from person import suspendAccount | 
					
						
							|  |  |  | from person import unsuspendAccount | 
					
						
							| 
									
										
										
										
											2019-08-13 13:58:48 +00:00
										 |  |  | from person import removeAccount | 
					
						
							| 
									
										
										
										
											2019-08-13 15:03:34 +00:00
										 |  |  | from person import canRemovePost | 
					
						
							| 
									
										
										
										
											2019-07-03 22:16:03 +00:00
										 |  |  | from posts import outboxMessageCreateWrap | 
					
						
							| 
									
										
										
										
											2019-07-04 16:24:23 +00:00
										 |  |  | from posts import savePostToBox | 
					
						
							| 
									
										
										
										
											2019-07-15 17:22:51 +00:00
										 |  |  | from posts import sendToFollowers | 
					
						
							|  |  |  | from posts import postIsAddressedToPublic | 
					
						
							| 
									
										
										
										
											2019-07-15 18:20:52 +00:00
										 |  |  | from posts import sendToNamedAddresses | 
					
						
							| 
									
										
										
										
											2019-07-27 22:48:34 +00:00
										 |  |  | from posts import createPublicPost | 
					
						
							| 
									
										
										
										
											2019-08-11 11:25:27 +00:00
										 |  |  | from posts import createReportPost | 
					
						
							| 
									
										
										
										
											2019-07-28 11:08:14 +00:00
										 |  |  | from posts import createUnlistedPost | 
					
						
							| 
									
										
										
										
											2019-07-27 22:48:34 +00:00
										 |  |  | from posts import createFollowersOnlyPost | 
					
						
							|  |  |  | from posts import createDirectMessagePost | 
					
						
							| 
									
										
										
										
											2019-08-02 18:37:23 +00:00
										 |  |  | from posts import populateRepliesJson | 
					
						
							| 
									
										
										
										
											2019-08-18 09:39:12 +00:00
										 |  |  | from posts import addToField | 
					
						
							| 
									
										
										
										
											2019-08-20 11:51:29 +00:00
										 |  |  | from posts import expireCache | 
					
						
							| 
									
										
										
										
											2019-06-28 21:59:54 +00:00
										 |  |  | from inbox import inboxPermittedMessage | 
					
						
							| 
									
										
										
										
											2019-07-02 15:07:27 +00:00
										 |  |  | from inbox import inboxMessageHasParams | 
					
						
							| 
									
										
										
										
											2019-07-04 12:23:53 +00:00
										 |  |  | from inbox import runInboxQueue | 
					
						
							| 
									
										
										
										
											2019-07-04 14:36:29 +00:00
										 |  |  | from inbox import savePostToInboxQueue | 
					
						
							| 
									
										
										
										
											2019-08-02 18:04:31 +00:00
										 |  |  | from inbox import populateReplies | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  | from follow import getFollowingFeed | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  | from follow import outboxUndoFollow | 
					
						
							| 
									
										
										
										
											2019-07-29 16:13:48 +00:00
										 |  |  | from follow import sendFollowRequest | 
					
						
							| 
									
										
										
										
											2019-07-03 18:24:44 +00:00
										 |  |  | from auth import authorize | 
					
						
							| 
									
										
										
										
											2019-07-16 16:08:21 +00:00
										 |  |  | from auth import createPassword | 
					
						
							| 
									
										
										
										
											2019-07-24 22:38:42 +00:00
										 |  |  | from auth import createBasicAuthHeader | 
					
						
							|  |  |  | from auth import authorizeBasic | 
					
						
							| 
									
										
										
										
											2019-07-04 12:23:53 +00:00
										 |  |  | from threads import threadWithTrace | 
					
						
							| 
									
										
										
										
											2019-07-16 16:08:21 +00:00
										 |  |  | from media import getMediaPath | 
					
						
							|  |  |  | from media import createMediaDirs | 
					
						
							| 
									
										
										
										
											2019-07-17 17:16:48 +00:00
										 |  |  | from delete import outboxDelete | 
					
						
							| 
									
										
										
										
											2019-07-17 19:31:52 +00:00
										 |  |  | from like import outboxLike | 
					
						
							| 
									
										
										
										
											2019-07-17 19:55:24 +00:00
										 |  |  | from like import outboxUndoLike | 
					
						
							| 
									
										
										
										
											2019-07-17 21:40:56 +00:00
										 |  |  | from blocking import outboxBlock | 
					
						
							|  |  |  | from blocking import outboxUndoBlock | 
					
						
							| 
									
										
										
										
											2019-08-02 14:36:03 +00:00
										 |  |  | from blocking import addBlock | 
					
						
							|  |  |  | from blocking import removeBlock | 
					
						
							| 
									
										
										
										
											2019-08-13 15:45:47 +00:00
										 |  |  | from blocking import addGlobalBlock | 
					
						
							|  |  |  | from blocking import removeGlobalBlock | 
					
						
							| 
									
										
										
										
											2019-08-14 10:32:15 +00:00
										 |  |  | from blocking import isBlockedHashtag | 
					
						
							| 
									
										
										
										
											2019-07-18 13:10:26 +00:00
										 |  |  | from config import setConfigParam | 
					
						
							| 
									
										
										
										
											2019-08-12 21:20:47 +00:00
										 |  |  | from config import getConfigParam | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  | from roles import outboxDelegate | 
					
						
							| 
									
										
										
										
											2019-08-12 21:20:47 +00:00
										 |  |  | from roles import setRole | 
					
						
							|  |  |  | from roles import clearModeratorStatus | 
					
						
							| 
									
										
										
										
											2019-07-19 10:01:24 +00:00
										 |  |  | from skills import outboxSkills | 
					
						
							| 
									
										
										
										
											2019-07-19 11:38:37 +00:00
										 |  |  | from availability import outboxAvailability | 
					
						
							| 
									
										
										
										
											2019-08-27 12:47:11 +00:00
										 |  |  | from webinterface import htmlDeletePost | 
					
						
							| 
									
										
										
										
											2019-08-26 16:02:47 +00:00
										 |  |  | from webinterface import htmlAbout | 
					
						
							| 
									
										
										
										
											2019-08-26 09:13:26 +00:00
										 |  |  | from webinterface import htmlRemoveSharedItem | 
					
						
							| 
									
										
										
										
											2019-08-25 17:34:09 +00:00
										 |  |  | from webinterface import htmlInboxDMs | 
					
						
							| 
									
										
										
										
											2019-08-24 23:00:03 +00:00
										 |  |  | from webinterface import htmlUnblockConfirm | 
					
						
							| 
									
										
										
										
											2019-08-24 21:10:20 +00:00
										 |  |  | from webinterface import htmlPersonOptions | 
					
						
							| 
									
										
										
										
											2019-07-20 21:13:36 +00:00
										 |  |  | from webinterface import htmlIndividualPost | 
					
						
							|  |  |  | from webinterface import htmlProfile | 
					
						
							|  |  |  | from webinterface import htmlInbox | 
					
						
							|  |  |  | from webinterface import htmlOutbox | 
					
						
							| 
									
										
										
										
											2019-08-12 13:22:17 +00:00
										 |  |  | from webinterface import htmlModeration | 
					
						
							| 
									
										
										
										
											2019-07-20 21:13:36 +00:00
										 |  |  | from webinterface import htmlPostReplies | 
					
						
							| 
									
										
										
										
											2019-07-24 22:38:42 +00:00
										 |  |  | from webinterface import htmlLogin | 
					
						
							| 
									
										
										
										
											2019-08-13 09:24:55 +00:00
										 |  |  | from webinterface import htmlSuspended | 
					
						
							| 
									
										
										
										
											2019-07-24 22:38:42 +00:00
										 |  |  | from webinterface import htmlGetLoginCredentials | 
					
						
							| 
									
										
										
										
											2019-07-25 21:39:09 +00:00
										 |  |  | from webinterface import htmlNewPost | 
					
						
							| 
									
										
										
										
											2019-07-29 09:49:46 +00:00
										 |  |  | from webinterface import htmlFollowConfirm | 
					
						
							| 
									
										
										
										
											2019-07-30 22:34:04 +00:00
										 |  |  | from webinterface import htmlSearch | 
					
						
							| 
									
										
										
										
											2019-08-19 19:02:28 +00:00
										 |  |  | from webinterface import htmlSearchEmoji | 
					
						
							| 
									
										
										
										
											2019-08-19 20:01:29 +00:00
										 |  |  | from webinterface import htmlSearchEmojiTextEntry | 
					
						
							| 
									
										
										
										
											2019-07-29 20:36:26 +00:00
										 |  |  | from webinterface import htmlUnfollowConfirm | 
					
						
							| 
									
										
										
										
											2019-07-30 22:34:04 +00:00
										 |  |  | from webinterface import htmlProfileAfterSearch | 
					
						
							| 
									
										
										
										
											2019-08-02 09:52:12 +00:00
										 |  |  | from webinterface import htmlEditProfile | 
					
						
							| 
									
										
										
										
											2019-08-08 13:38:33 +00:00
										 |  |  | from webinterface import htmlTermsOfService | 
					
						
							| 
									
										
										
										
											2019-08-27 23:01:40 +00:00
										 |  |  | from webinterface import htmlSkillsSearch | 
					
						
							| 
									
										
										
										
											2019-08-10 10:54:52 +00:00
										 |  |  | from webinterface import htmlHashtagSearch | 
					
						
							| 
									
										
										
										
											2019-08-13 17:25:39 +00:00
										 |  |  | from webinterface import htmlModerationInfo | 
					
						
							| 
									
										
										
										
											2019-08-13 21:32:18 +00:00
										 |  |  | from webinterface import htmlSearchSharedItems | 
					
						
							| 
									
										
										
										
											2019-08-14 10:32:15 +00:00
										 |  |  | from webinterface import htmlHashtagBlocked | 
					
						
							| 
									
										
										
										
											2019-07-23 12:33:09 +00:00
										 |  |  | from shares import getSharesFeedForPerson | 
					
						
							| 
									
										
										
										
											2019-07-23 20:00:17 +00:00
										 |  |  | from shares import outboxShareUpload | 
					
						
							| 
									
										
										
										
											2019-07-23 21:14:16 +00:00
										 |  |  | from shares import outboxUndoShareUpload | 
					
						
							| 
									
										
										
										
											2019-07-28 08:34:49 +00:00
										 |  |  | from shares import addShare | 
					
						
							| 
									
										
										
										
											2019-08-26 09:31:45 +00:00
										 |  |  | from shares import removeShare | 
					
						
							| 
									
										
										
										
											2019-07-29 16:13:48 +00:00
										 |  |  | from utils import getNicknameFromActor | 
					
						
							|  |  |  | from utils import getDomainFromActor | 
					
						
							| 
									
										
										
										
											2019-08-21 17:13:08 +00:00
										 |  |  | from utils import getStatusNumber | 
					
						
							| 
									
										
										
										
											2019-07-29 19:14:14 +00:00
										 |  |  | from manualapprove import manualDenyFollowRequest | 
					
						
							|  |  |  | from manualapprove import manualApproveFollowRequest | 
					
						
							| 
									
										
										
										
											2019-07-31 16:47:45 +00:00
										 |  |  | from announce import createAnnounce | 
					
						
							| 
									
										
										
										
											2019-08-01 11:43:22 +00:00
										 |  |  | from announce import outboxAnnounce | 
					
						
							| 
									
										
										
										
											2019-08-09 09:09:21 +00:00
										 |  |  | from content import addHtmlTags | 
					
						
							| 
									
										
										
										
											2019-08-02 09:52:12 +00:00
										 |  |  | from media import removeMetaData | 
					
						
							| 
									
										
										
										
											2019-08-22 15:14:05 +00:00
										 |  |  | from cache import storePersonInCache | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											2019-06-28 21:06:05 +00:00
										 |  |  | import sys | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-29 14:35:26 +00:00
										 |  |  | # maximum number of posts to list in outbox feed | 
					
						
							| 
									
										
										
										
											2019-07-31 20:41:17 +00:00
										 |  |  | maxPostsInFeed=12 | 
					
						
							| 
									
										
										
										
											2019-06-29 14:35:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  | # number of follows/followers per page | 
					
						
							| 
									
										
										
										
											2019-06-29 20:34:41 +00:00
										 |  |  | followsPerPage=12 | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-23 12:33:09 +00:00
										 |  |  | # number of item shares per page | 
					
						
							|  |  |  | sharesPerPage=12 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  | def readFollowList(filename: str): | 
					
						
							|  |  |  |     """Returns a list of ActivityPub addresses to follow
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     followlist=[] | 
					
						
							|  |  |  |     if not os.path.isfile(filename): | 
					
						
							|  |  |  |         return followlist | 
					
						
							|  |  |  |     followUsers = open(filename, "r")     | 
					
						
							|  |  |  |     for u in followUsers: | 
					
						
							|  |  |  |         if u not in followlist: | 
					
						
							| 
									
										
										
										
											2019-07-03 09:40:27 +00:00
										 |  |  |             nickname,domain = parseHandle(u) | 
					
						
							|  |  |  |             if nickname: | 
					
						
							|  |  |  |                 followlist.append(nickname+'@'+domain) | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  |     followUsers.close() | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |     return followlist | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class PubServer(BaseHTTPRequestHandler): | 
					
						
							| 
									
										
										
										
											2019-08-17 10:15:45 +00:00
										 |  |  |     protocol_version = 'HTTP/1.1' | 
					
						
							| 
									
										
										
										
											2019-08-15 14:21:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-24 11:23:12 +00:00
										 |  |  |     def _requestHTTP(self) -> bool: | 
					
						
							|  |  |  |         """Should a http response be given?
 | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2019-08-27 16:27:48 +00:00
										 |  |  |         if 'image/' in self.headers['Accept']: | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  |         if self.headers['Accept'].startswith('*'): | 
					
						
							| 
									
										
										
										
											2019-08-24 11:28:43 +00:00
										 |  |  |             return False | 
					
						
							| 
									
										
										
										
											2019-08-24 11:23:12 +00:00
										 |  |  |         if 'json' in self.headers['Accept']: | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  |         return True | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |     def _login_headers(self,fileFormat: str,length: int) -> None: | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |         self.send_response(200) | 
					
						
							|  |  |  |         self.send_header('Content-type', fileFormat) | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |         self.send_header('Content-Length', str(length)) | 
					
						
							| 
									
										
										
										
											2019-07-25 09:13:02 +00:00
										 |  |  |         self.send_header('Host', self.server.domainFull) | 
					
						
							| 
									
										
										
										
											2019-07-25 10:56:24 +00:00
										 |  |  |         self.send_header('WWW-Authenticate', 'title="Login to Epicyon", Basic realm="epicyon"') | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |         self.end_headers() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |     def _set_headers(self,fileFormat: str,length: int,cookie: str) -> None: | 
					
						
							| 
									
										
										
										
											2019-08-15 12:22:34 +00:00
										 |  |  |         self.send_response(200) | 
					
						
							|  |  |  |         self.send_header('Content-type', fileFormat) | 
					
						
							|  |  |  |         self.send_header('Content-Length', str(length)) | 
					
						
							|  |  |  |         if cookie: | 
					
						
							|  |  |  |             self.send_header('Cookie', cookie) | 
					
						
							|  |  |  |         self.send_header('Host', self.server.domainFull) | 
					
						
							|  |  |  |         self.send_header('InstanceID', self.server.instanceId) | 
					
						
							|  |  |  |         self.end_headers() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-29 16:13:48 +00:00
										 |  |  |     def _redirect_headers(self,redirect: str,cookie: str) -> None: | 
					
						
							| 
									
										
										
										
											2019-07-28 14:09:48 +00:00
										 |  |  |         self.send_response(303) | 
					
						
							| 
									
										
										
										
											2019-08-15 14:50:47 +00:00
										 |  |  |         #self.send_header('Content-type', 'text/html') | 
					
						
							| 
									
										
										
										
											2019-07-29 16:13:48 +00:00
										 |  |  |         if cookie: | 
					
						
							|  |  |  |             self.send_header('Cookie', cookie) | 
					
						
							| 
									
										
										
										
											2019-07-28 14:09:48 +00:00
										 |  |  |         self.send_header('Location', redirect) | 
					
						
							|  |  |  |         self.send_header('Host', self.server.domainFull) | 
					
						
							| 
									
										
										
										
											2019-08-02 12:49:34 +00:00
										 |  |  |         self.send_header('InstanceID', self.server.instanceId) | 
					
						
							| 
									
										
										
										
											2019-08-15 14:50:47 +00:00
										 |  |  |         self.send_header('Content-Length', '0') | 
					
						
							| 
									
										
										
										
											2019-07-28 14:09:48 +00:00
										 |  |  |         self.end_headers() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-03 22:16:03 +00:00
										 |  |  |     def _404(self) -> None: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |         msg="<html><head></head><body><h1>404 Not Found</h1></body></html>".encode('utf-8') | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |         self.send_response(404) | 
					
						
							|  |  |  |         self.send_header('Content-Type', 'text/html; charset=utf-8') | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |         self.send_header('Content-Length', str(len(msg))) | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |         self.end_headers() | 
					
						
							| 
									
										
										
										
											2019-08-16 19:45:48 +00:00
										 |  |  |         try: | 
					
						
							|  |  |  |             self.wfile.write(msg) | 
					
						
							|  |  |  |         except Exception as e: | 
					
						
							|  |  |  |             print('Error when showing 404') | 
					
						
							|  |  |  |             print(e) | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-25 14:24:42 +00:00
										 |  |  |     def _webfinger(self) -> bool: | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |         if not self.path.startswith('/.well-known'): | 
					
						
							|  |  |  |             return False | 
					
						
							| 
									
										
										
										
											2019-07-04 14:36:29 +00:00
										 |  |  |         if self.server.debug: | 
					
						
							|  |  |  |             print('DEBUG: WEBFINGER well-known') | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-03 16:14:45 +00:00
										 |  |  |         if self.server.debug: | 
					
						
							|  |  |  |             print('DEBUG: WEBFINGER host-meta') | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |         if self.path.startswith('/.well-known/host-meta'): | 
					
						
							| 
									
										
										
										
											2019-08-16 20:52:55 +00:00
										 |  |  |             wfResult=webfingerMeta(self.server.httpPrefix,self.server.domainFull) | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |             if wfResult: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                 msg=wfResult.encode('utf-8') | 
					
						
							|  |  |  |                 self._set_headers('application/xrd+xml',len(msg),None) | 
					
						
							|  |  |  |                 self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-03 16:14:45 +00:00
										 |  |  |         if self.server.debug: | 
					
						
							|  |  |  |             print('DEBUG: WEBFINGER lookup '+self.path+' '+str(self.server.baseDir)) | 
					
						
							| 
									
										
										
										
											2019-07-19 14:41:32 +00:00
										 |  |  |         wfResult=webfingerLookup(self.path,self.server.baseDir,self.server.port,self.server.debug) | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |         if wfResult: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |             msg=json.dumps(wfResult).encode('utf-8') | 
					
						
							|  |  |  |             self._set_headers('application/jrd+json',len(msg),None) | 
					
						
							|  |  |  |             self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2019-07-03 16:14:45 +00:00
										 |  |  |             if self.server.debug: | 
					
						
							|  |  |  |                 print('DEBUG: WEBFINGER lookup 404 '+self.path) | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |             self._404() | 
					
						
							|  |  |  |         return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-03 22:16:03 +00:00
										 |  |  |     def _permittedDir(self,path: str) -> bool: | 
					
						
							|  |  |  |         """These are special paths which should not be accessible
 | 
					
						
							|  |  |  |         directly via GET or POST | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |         if path.startswith('/wfendpoints') or \ | 
					
						
							|  |  |  |            path.startswith('/keys') or \ | 
					
						
							|  |  |  |            path.startswith('/accounts'): | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  |         return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-05 11:41:09 +00:00
										 |  |  |     def _postToOutbox(self,messageJson: {}) -> bool: | 
					
						
							| 
									
										
										
										
											2019-07-03 22:16:03 +00:00
										 |  |  |         """post is received by the outbox
 | 
					
						
							|  |  |  |         Client to server message post | 
					
						
							|  |  |  |         https://www.w3.org/TR/activitypub/#client-to-server-outbox-delivery | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2019-07-03 22:59:56 +00:00
										 |  |  |         if not messageJson.get('type'): | 
					
						
							| 
									
										
										
										
											2019-07-04 10:02:56 +00:00
										 |  |  |             if self.server.debug: | 
					
						
							|  |  |  |                 print('DEBUG: POST to outbox has no "type" parameter') | 
					
						
							| 
									
										
										
										
											2019-07-03 22:59:56 +00:00
										 |  |  |             return False | 
					
						
							|  |  |  |         if not messageJson.get('object') and messageJson.get('content'): | 
					
						
							|  |  |  |             if messageJson['type']!='Create': | 
					
						
							|  |  |  |                 # https://www.w3.org/TR/activitypub/#object-without-create | 
					
						
							|  |  |  |                 if self.server.debug: | 
					
						
							| 
									
										
										
										
											2019-07-04 10:02:56 +00:00
										 |  |  |                     print('DEBUG: POST to outbox - adding Create wrapper') | 
					
						
							| 
									
										
										
										
											2019-07-03 22:59:56 +00:00
										 |  |  |                 messageJson= \ | 
					
						
							|  |  |  |                     outboxMessageCreateWrap(self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                             self.postToNickname, \ | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |                                             self.server.domain, \ | 
					
						
							|  |  |  |                                             self.server.port, \ | 
					
						
							|  |  |  |                                             messageJson) | 
					
						
							| 
									
										
										
										
											2019-07-03 22:44:03 +00:00
										 |  |  |         if messageJson['type']=='Create': | 
					
						
							|  |  |  |             if not (messageJson.get('id') and \ | 
					
						
							|  |  |  |                     messageJson.get('type') and \ | 
					
						
							|  |  |  |                     messageJson.get('actor') and \ | 
					
						
							|  |  |  |                     messageJson.get('object') and \ | 
					
						
							|  |  |  |                     messageJson.get('to')): | 
					
						
							|  |  |  |                 if self.server.debug: | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |                     pprint(messageJson) | 
					
						
							| 
									
										
										
										
											2019-07-04 10:02:56 +00:00
										 |  |  |                     print('DEBUG: POST to outbox - Create does not have the required parameters') | 
					
						
							| 
									
										
										
										
											2019-07-03 22:44:03 +00:00
										 |  |  |                 return False | 
					
						
							|  |  |  |             # https://www.w3.org/TR/activitypub/#create-activity-outbox | 
					
						
							|  |  |  |             messageJson['object']['attributedTo']=messageJson['actor'] | 
					
						
							| 
									
										
										
										
											2019-07-16 16:08:21 +00:00
										 |  |  |             if messageJson['object'].get('attachment'): | 
					
						
							|  |  |  |                 attachmentIndex=0 | 
					
						
							|  |  |  |                 if messageJson['object']['attachment'][attachmentIndex].get('mediaType'): | 
					
						
							|  |  |  |                     fileExtension='png' | 
					
						
							|  |  |  |                     if messageJson['object']['attachment'][attachmentIndex]['mediaType'].endswith('jpeg'): | 
					
						
							|  |  |  |                         fileExtension='jpg' | 
					
						
							|  |  |  |                     if messageJson['object']['attachment'][attachmentIndex]['mediaType'].endswith('gif'): | 
					
						
							|  |  |  |                         fileExtension='gif' | 
					
						
							|  |  |  |                     mediaDir=self.server.baseDir+'/accounts/'+self.postToNickname+'@'+self.server.domain | 
					
						
							|  |  |  |                     uploadMediaFilename=mediaDir+'/upload.'+fileExtension | 
					
						
							|  |  |  |                     if not os.path.isfile(uploadMediaFilename): | 
					
						
							|  |  |  |                         del messageJson['object']['attachment'] | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         # generate a path for the uploaded image | 
					
						
							|  |  |  |                         mPath=getMediaPath() | 
					
						
							|  |  |  |                         mediaPath=mPath+'/'+createPassword(32)+'.'+fileExtension | 
					
						
							|  |  |  |                         createMediaDirs(self.server.baseDir,mPath) | 
					
						
							|  |  |  |                         mediaFilename=self.server.baseDir+'/'+mediaPath | 
					
						
							|  |  |  |                         # move the uploaded image to its new path | 
					
						
							|  |  |  |                         os.rename(uploadMediaFilename,mediaFilename) | 
					
						
							|  |  |  |                         # change the url of the attachment | 
					
						
							|  |  |  |                         messageJson['object']['attachment'][attachmentIndex]['url']= \ | 
					
						
							| 
									
										
										
										
											2019-07-28 18:06:20 +00:00
										 |  |  |                             self.server.httpPrefix+'://'+self.server.domainFull+'/'+mediaPath | 
					
						
							| 
									
										
										
										
											2019-07-16 16:08:21 +00:00
										 |  |  |                  | 
					
						
							| 
									
										
										
										
											2019-07-06 17:00:22 +00:00
										 |  |  |         permittedOutboxTypes=[ | 
					
						
							|  |  |  |             'Create','Announce','Like','Follow','Undo', \ | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |             'Update','Add','Remove','Block','Delete', \ | 
					
						
							| 
									
										
										
										
											2019-07-19 10:01:24 +00:00
										 |  |  |             'Delegate','Skill' | 
					
						
							| 
									
										
										
										
											2019-07-06 17:00:22 +00:00
										 |  |  |         ] | 
					
						
							| 
									
										
										
										
											2019-07-03 22:44:03 +00:00
										 |  |  |         if messageJson['type'] not in permittedOutboxTypes: | 
					
						
							|  |  |  |             if self.server.debug: | 
					
						
							| 
									
										
										
										
											2019-07-06 17:00:22 +00:00
										 |  |  |                 print('DEBUG: POST to outbox - '+messageJson['type']+ \ | 
					
						
							|  |  |  |                       ' is not a permitted activity type') | 
					
						
							| 
									
										
										
										
											2019-07-03 22:16:03 +00:00
										 |  |  |             return False | 
					
						
							| 
									
										
										
										
											2019-07-03 22:59:56 +00:00
										 |  |  |         if messageJson.get('id'): | 
					
						
							| 
									
										
										
										
											2019-08-16 19:48:32 +00:00
										 |  |  |             postId=messageJson['id'].replace('/activity','').replace('/undo','') | 
					
						
							| 
									
										
										
										
											2019-07-18 11:35:48 +00:00
										 |  |  |             if self.server.debug: | 
					
						
							|  |  |  |                 print('DEBUG: id attribute exists within POST to outbox') | 
					
						
							| 
									
										
										
										
											2019-07-03 22:59:56 +00:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2019-07-18 11:35:48 +00:00
										 |  |  |             if self.server.debug: | 
					
						
							|  |  |  |                 print('DEBUG: No id attribute within POST to outbox') | 
					
						
							| 
									
										
										
										
											2019-07-03 22:59:56 +00:00
										 |  |  |             postId=None | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |         if self.server.debug: | 
					
						
							|  |  |  |             pprint(messageJson) | 
					
						
							| 
									
										
										
										
											2019-07-17 17:16:48 +00:00
										 |  |  |             print('DEBUG: savePostToBox') | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |         savePostToBox(self.server.baseDir, \ | 
					
						
							|  |  |  |                       self.server.httpPrefix, \ | 
					
						
							|  |  |  |                       postId, \ | 
					
						
							| 
									
										
										
										
											2019-07-15 18:20:52 +00:00
										 |  |  |                       self.postToNickname, \ | 
					
						
							| 
									
										
										
										
											2019-08-08 08:51:32 +00:00
										 |  |  |                       self.server.domainFull,messageJson,'outbox') | 
					
						
							| 
									
										
										
										
											2019-08-01 11:43:22 +00:00
										 |  |  |         if outboxAnnounce(self.server.baseDir,messageJson,self.server.debug): | 
					
						
							|  |  |  |             if self.server.debug: | 
					
						
							|  |  |  |                 print('DEBUG: Updated announcements (shares) collection for the post associated with the Announce activity') | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |         if not self.server.session: | 
					
						
							| 
									
										
										
										
											2019-07-16 10:20:03 +00:00
										 |  |  |             if self.server.debug: | 
					
						
							|  |  |  |                 print('DEBUG: creating new session for c2s') | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |             self.server.session= \ | 
					
						
							|  |  |  |                 createSession(self.server.domain,self.server.port,self.server.useTor) | 
					
						
							| 
									
										
										
										
											2019-07-15 17:22:51 +00:00
										 |  |  |         if self.server.debug: | 
					
						
							|  |  |  |             print('DEBUG: sending c2s post to followers') | 
					
						
							|  |  |  |         sendToFollowers(self.server.session,self.server.baseDir, \ | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |                         self.postToNickname,self.server.domain, \ | 
					
						
							|  |  |  |                         self.server.port, \ | 
					
						
							|  |  |  |                         self.server.httpPrefix, \ | 
					
						
							|  |  |  |                         self.server.federationList, \ | 
					
						
							|  |  |  |                         self.server.sendThreads, \ | 
					
						
							|  |  |  |                         self.server.postLog, \ | 
					
						
							|  |  |  |                         self.server.cachedWebfingers, \ | 
					
						
							|  |  |  |                         self.server.personCache, \ | 
					
						
							| 
									
										
										
										
											2019-08-14 20:12:27 +00:00
										 |  |  |                         messageJson,self.server.debug, \ | 
					
						
							|  |  |  |                         self.server.projectVersion) | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  |         if self.server.debug: | 
					
						
							|  |  |  |             print('DEBUG: handle any unfollow requests') | 
					
						
							|  |  |  |         outboxUndoFollow(self.server.baseDir,messageJson,self.server.debug) | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |         if self.server.debug: | 
					
						
							|  |  |  |             print('DEBUG: handle delegation requests') | 
					
						
							| 
									
										
										
										
											2019-07-19 10:01:24 +00:00
										 |  |  |         outboxDelegate(self.server.baseDir,self.postToNickname,messageJson,self.server.debug) | 
					
						
							|  |  |  |         if self.server.debug: | 
					
						
							| 
									
										
										
										
											2019-07-19 11:38:37 +00:00
										 |  |  |             print('DEBUG: handle skills changes requests') | 
					
						
							| 
									
										
										
										
											2019-07-19 10:01:24 +00:00
										 |  |  |         outboxSkills(self.server.baseDir,self.postToNickname,messageJson,self.server.debug) | 
					
						
							| 
									
										
										
										
											2019-07-19 11:38:37 +00:00
										 |  |  |         if self.server.debug: | 
					
						
							|  |  |  |             print('DEBUG: handle availability changes requests') | 
					
						
							|  |  |  |         outboxAvailability(self.server.baseDir,self.postToNickname,messageJson,self.server.debug) | 
					
						
							| 
									
										
										
										
											2019-07-17 19:31:52 +00:00
										 |  |  |         if self.server.debug: | 
					
						
							|  |  |  |             print('DEBUG: handle any like requests') | 
					
						
							|  |  |  |         outboxLike(self.server.baseDir,self.server.httpPrefix, \ | 
					
						
							|  |  |  |                    self.postToNickname,self.server.domain,self.server.port, \ | 
					
						
							|  |  |  |                    messageJson,self.server.debug) | 
					
						
							| 
									
										
										
										
											2019-07-17 19:55:24 +00:00
										 |  |  |         if self.server.debug: | 
					
						
							|  |  |  |             print('DEBUG: handle any undo like requests') | 
					
						
							|  |  |  |         outboxUndoLike(self.server.baseDir,self.server.httpPrefix, \ | 
					
						
							|  |  |  |                        self.postToNickname,self.server.domain,self.server.port, \ | 
					
						
							|  |  |  |                        messageJson,self.server.debug) | 
					
						
							| 
									
										
										
										
											2019-08-12 18:02:29 +00:00
										 |  |  |         if self.server.debug: | 
					
						
							|  |  |  |             print('DEBUG: handle delete requests')         | 
					
						
							|  |  |  |         outboxDelete(self.server.baseDir,self.server.httpPrefix, \ | 
					
						
							|  |  |  |                      self.postToNickname,self.server.domain, \ | 
					
						
							|  |  |  |                      messageJson,self.server.debug, \ | 
					
						
							|  |  |  |                      self.server.allowDeletion) | 
					
						
							| 
									
										
										
										
											2019-07-17 21:40:56 +00:00
										 |  |  |         if self.server.debug: | 
					
						
							|  |  |  |             print('DEBUG: handle block requests') | 
					
						
							|  |  |  |         outboxBlock(self.server.baseDir,self.server.httpPrefix, \ | 
					
						
							|  |  |  |                     self.postToNickname,self.server.domain, \ | 
					
						
							|  |  |  |                     self.server.port, | 
					
						
							|  |  |  |                     messageJson,self.server.debug) | 
					
						
							|  |  |  |         if self.server.debug: | 
					
						
							|  |  |  |             print('DEBUG: handle undo block requests') | 
					
						
							|  |  |  |         outboxUndoBlock(self.server.baseDir,self.server.httpPrefix, \ | 
					
						
							|  |  |  |                         self.postToNickname,self.server.domain, \ | 
					
						
							|  |  |  |                         self.server.port, | 
					
						
							|  |  |  |                         messageJson,self.server.debug) | 
					
						
							| 
									
										
										
										
											2019-07-23 20:00:17 +00:00
										 |  |  |         if self.server.debug: | 
					
						
							|  |  |  |             print('DEBUG: handle share uploads') | 
					
						
							|  |  |  |         outboxShareUpload(self.server.baseDir,self.server.httpPrefix, \ | 
					
						
							|  |  |  |                           self.postToNickname,self.server.domain, \ | 
					
						
							|  |  |  |                           self.server.port, | 
					
						
							|  |  |  |                           messageJson,self.server.debug) | 
					
						
							| 
									
										
										
										
											2019-07-23 21:14:16 +00:00
										 |  |  |         if self.server.debug: | 
					
						
							|  |  |  |             print('DEBUG: handle undo share uploads') | 
					
						
							|  |  |  |         outboxUndoShareUpload(self.server.baseDir,self.server.httpPrefix, \ | 
					
						
							|  |  |  |                               self.postToNickname,self.server.domain, \ | 
					
						
							|  |  |  |                               self.server.port, | 
					
						
							|  |  |  |                               messageJson,self.server.debug) | 
					
						
							| 
									
										
										
										
											2019-07-15 18:20:52 +00:00
										 |  |  |         if self.server.debug: | 
					
						
							|  |  |  |             print('DEBUG: sending c2s post to named addresses') | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |             print('c2s sender: '+self.postToNickname+'@'+self.server.domain+':'+str(self.server.port)) | 
					
						
							| 
									
										
										
										
											2019-07-15 18:20:52 +00:00
										 |  |  |         sendToNamedAddresses(self.server.session,self.server.baseDir, \ | 
					
						
							|  |  |  |                              self.postToNickname,self.server.domain, \ | 
					
						
							|  |  |  |                              self.server.port, \ | 
					
						
							|  |  |  |                              self.server.httpPrefix, \ | 
					
						
							|  |  |  |                              self.server.federationList, \ | 
					
						
							|  |  |  |                              self.server.sendThreads, \ | 
					
						
							|  |  |  |                              self.server.postLog, \ | 
					
						
							|  |  |  |                              self.server.cachedWebfingers, \ | 
					
						
							|  |  |  |                              self.server.personCache, \ | 
					
						
							| 
									
										
										
										
											2019-08-14 20:12:27 +00:00
										 |  |  |                              messageJson,self.server.debug, \ | 
					
						
							|  |  |  |                              self.server.projectVersion) | 
					
						
							| 
									
										
										
										
											2019-07-03 22:16:03 +00:00
										 |  |  |         return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-16 17:19:23 +00:00
										 |  |  |     def _updateInboxQueue(self,nickname: str,messageJson: {},messageBytes: str) -> int: | 
					
						
							| 
									
										
										
										
											2019-07-05 11:27:18 +00:00
										 |  |  |         """Update the inbox queue
 | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2019-07-15 12:27:26 +00:00
										 |  |  |         # Check if the queue is full | 
					
						
							|  |  |  |         if len(self.server.inboxQueue)>=self.server.maxQueueLength: | 
					
						
							| 
									
										
										
										
											2019-08-05 21:14:38 +00:00
										 |  |  |             print('Inbox queue is full') | 
					
						
							| 
									
										
										
										
											2019-07-15 12:27:26 +00:00
										 |  |  |             return 1 | 
					
						
							| 
									
										
										
										
											2019-08-15 22:12:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-16 08:39:01 +00:00
										 |  |  |         # Convert the headers needed for signature verification to dict | 
					
						
							| 
									
										
										
										
											2019-08-15 22:12:58 +00:00
										 |  |  |         headersDict={} | 
					
						
							|  |  |  |         headersDict['host']=self.headers['host'] | 
					
						
							|  |  |  |         headersDict['signature']=self.headers['signature'] | 
					
						
							|  |  |  |         if self.headers.get('Date'): | 
					
						
							|  |  |  |             headersDict['Date']=self.headers['Date'] | 
					
						
							|  |  |  |         if self.headers.get('digest'): | 
					
						
							|  |  |  |             headersDict['digest']=self.headers['digest'] | 
					
						
							|  |  |  |         if self.headers.get('Content-type'): | 
					
						
							|  |  |  |             headersDict['Content-type']=self.headers['Content-type'] | 
					
						
							| 
									
										
										
										
											2019-08-18 09:39:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # For follow activities add a 'to' field, which is a copy of the object field | 
					
						
							|  |  |  |         messageJson,toFieldExists=addToField('Follow',messageJson,self.server.debug) | 
					
						
							| 
									
										
										
										
											2019-08-18 16:49:35 +00:00
										 |  |  |          | 
					
						
							|  |  |  |         # For like activities add a 'to' field, which is a copy of the actor within the object field | 
					
						
							|  |  |  |         messageJson,toFieldExists=addToField('Like',messageJson,self.server.debug) | 
					
						
							| 
									
										
										
										
											2019-08-18 09:39:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         pprint(messageJson) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-15 22:12:58 +00:00
										 |  |  |         # save the json for later queue processing | 
					
						
							| 
									
										
										
										
											2019-07-06 13:49:25 +00:00
										 |  |  |         queueFilename = \ | 
					
						
							| 
									
										
										
										
											2019-08-16 17:19:23 +00:00
										 |  |  |             savePostToInboxQueue(self.server.baseDir, | 
					
						
							|  |  |  |                                  self.server.httpPrefix, | 
					
						
							|  |  |  |                                  nickname, | 
					
						
							|  |  |  |                                  self.server.domainFull, | 
					
						
							| 
									
										
										
										
											2019-07-05 11:27:18 +00:00
										 |  |  |                                  messageJson, | 
					
						
							| 
									
										
										
										
											2019-08-16 17:19:23 +00:00
										 |  |  |                                  messageBytes.decode('utf-8'), | 
					
						
							| 
									
										
										
										
											2019-08-15 22:12:58 +00:00
										 |  |  |                                  headersDict, | 
					
						
							| 
									
										
										
										
											2019-08-16 08:39:01 +00:00
										 |  |  |                                  self.path, | 
					
						
							| 
									
										
										
										
											2019-07-06 13:49:25 +00:00
										 |  |  |                                  self.server.debug) | 
					
						
							|  |  |  |         if queueFilename: | 
					
						
							| 
									
										
										
										
											2019-07-15 12:27:26 +00:00
										 |  |  |             # add json to the queue | 
					
						
							| 
									
										
										
										
											2019-07-06 13:49:25 +00:00
										 |  |  |             if queueFilename not in self.server.inboxQueue: | 
					
						
							|  |  |  |                 self.server.inboxQueue.append(queueFilename) | 
					
						
							| 
									
										
										
										
											2019-07-05 11:27:18 +00:00
										 |  |  |             self.send_response(201) | 
					
						
							|  |  |  |             self.end_headers() | 
					
						
							|  |  |  |             self.server.POSTbusy=False | 
					
						
							| 
									
										
										
										
											2019-07-15 12:27:26 +00:00
										 |  |  |             return 0 | 
					
						
							|  |  |  |         return 2 | 
					
						
							| 
									
										
										
										
											2019-07-05 11:27:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-12 11:05:43 +00:00
										 |  |  |     def _isAuthorized(self) -> bool: | 
					
						
							| 
									
										
										
										
											2019-07-25 14:24:42 +00:00
										 |  |  |         # token based authenticated used by the web interface | 
					
						
							|  |  |  |         if self.headers.get('Cookie'): | 
					
						
							|  |  |  |             if '=' in self.headers['Cookie']: | 
					
						
							|  |  |  |                 tokenStr=self.headers['Cookie'].split('=',1)[1] | 
					
						
							|  |  |  |                 if self.server.tokensLookup.get(tokenStr): | 
					
						
							|  |  |  |                     nickname=self.server.tokensLookup[tokenStr] | 
					
						
							|  |  |  |                     if '/'+nickname+'/' in self.path: | 
					
						
							|  |  |  |                         return True | 
					
						
							|  |  |  |                     if self.path.endswith('/'+nickname): | 
					
						
							|  |  |  |                         return True | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  |         # basic auth | 
					
						
							| 
									
										
										
										
											2019-07-12 11:05:43 +00:00
										 |  |  |         if self.headers.get('Authorization'): | 
					
						
							|  |  |  |             if authorize(self.server.baseDir,self.path, \ | 
					
						
							|  |  |  |                          self.headers['Authorization'], \ | 
					
						
							|  |  |  |                          self.server.debug): | 
					
						
							|  |  |  |                 return True | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2019-07-25 11:18:35 +00:00
										 |  |  |     def do_GET(self):         | 
					
						
							| 
									
										
										
										
											2019-07-03 16:14:45 +00:00
										 |  |  |         if self.server.debug: | 
					
						
							| 
									
										
										
										
											2019-07-06 17:00:22 +00:00
										 |  |  |             print('DEBUG: GET from '+self.server.baseDir+ \ | 
					
						
							|  |  |  |                   ' path: '+self.path+' busy: '+ \ | 
					
						
							|  |  |  |                   str(self.server.GETbusy)) | 
					
						
							| 
									
										
										
										
											2019-07-25 11:18:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-25 14:24:42 +00:00
										 |  |  |         if self.server.debug: | 
					
						
							|  |  |  |             print(str(self.headers)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-29 16:13:48 +00:00
										 |  |  |         cookie=None | 
					
						
							|  |  |  |         if self.headers.get('Cookie'): | 
					
						
							|  |  |  |             cookie=self.headers['Cookie'] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-25 14:24:42 +00:00
										 |  |  |         # check authorization | 
					
						
							| 
									
										
										
										
											2019-07-25 11:18:35 +00:00
										 |  |  |         authorized = self._isAuthorized() | 
					
						
							|  |  |  |         if authorized: | 
					
						
							|  |  |  |             if self.server.debug: | 
					
						
							| 
									
										
										
										
											2019-07-25 14:24:42 +00:00
										 |  |  |                 print('GET Authorization granted') | 
					
						
							| 
									
										
										
										
											2019-07-25 11:18:35 +00:00
										 |  |  |         else: | 
					
						
							|  |  |  |             if self.server.debug: | 
					
						
							| 
									
										
										
										
											2019-07-25 14:24:42 +00:00
										 |  |  |                 print('GET Not authorized') | 
					
						
							| 
									
										
										
										
											2019-07-25 16:03:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-20 11:30:41 +00:00
										 |  |  |         if not self.server.session: | 
					
						
							|  |  |  |             self.server.session= \ | 
					
						
							|  |  |  |                 createSession(self.server.domain,self.server.port,self.server.useTor) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-24 09:07:05 +00:00
										 |  |  |         # is this a html request? | 
					
						
							|  |  |  |         htmlGET=False | 
					
						
							|  |  |  |         if self.headers.get('Accept'): | 
					
						
							| 
									
										
										
										
											2019-08-24 11:23:12 +00:00
										 |  |  |             if self._requestHTTP(): | 
					
						
							| 
									
										
										
										
											2019-08-24 09:07:05 +00:00
										 |  |  |                 htmlGET=True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # replace https://domain/@nick with https://domain/users/nick | 
					
						
							| 
									
										
										
										
											2019-08-24 09:33:25 +00:00
										 |  |  |         if self.path.startswith('/@'): | 
					
						
							| 
									
										
										
										
											2019-08-24 09:07:05 +00:00
										 |  |  |             self.path=self.path.replace('/@','/users/') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-05 11:08:52 +00:00
										 |  |  |         # treat shared inbox paths consistently | 
					
						
							| 
									
										
										
										
											2019-08-23 13:47:29 +00:00
										 |  |  |         if self.path=='/sharedInbox' or \ | 
					
						
							|  |  |  |            self.path=='/users/inbox' or \ | 
					
						
							| 
									
										
										
										
											2019-08-23 17:06:44 +00:00
										 |  |  |            self.path=='/actor/inbox' or \ | 
					
						
							| 
									
										
										
										
											2019-08-23 13:47:29 +00:00
										 |  |  |            self.path=='/users/'+self.server.domain: | 
					
						
							| 
									
										
										
										
											2019-08-05 11:08:52 +00:00
										 |  |  |             self.path='/inbox' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-24 21:14:33 +00:00
										 |  |  |         # show the person options screen with view/follow/block/report | 
					
						
							|  |  |  |         if htmlGET and '/users/' in self.path: | 
					
						
							|  |  |  |            if '?options=' in self.path: | 
					
						
							|  |  |  |                optionsStr=self.path.split('?options=')[1] | 
					
						
							|  |  |  |                originPathStr=self.path.split('?options=')[0] | 
					
						
							|  |  |  |                if ';' in optionsStr: | 
					
						
							| 
									
										
										
										
											2019-08-24 23:00:03 +00:00
										 |  |  |                    optionsList=optionsStr.split(';') | 
					
						
							|  |  |  |                    optionsActor=optionsList[0] | 
					
						
							|  |  |  |                    optionsProfileUrl=optionsList[1] | 
					
						
							|  |  |  |                    optionsLink=None | 
					
						
							|  |  |  |                    if len(optionsList)>2: | 
					
						
							|  |  |  |                        optionsLink=optionsList[2] | 
					
						
							|  |  |  |                    msg=htmlPersonOptions(self.server.baseDir, \ | 
					
						
							|  |  |  |                                          self.server.domain, \ | 
					
						
							|  |  |  |                                          originPathStr, \ | 
					
						
							|  |  |  |                                          optionsActor, \ | 
					
						
							|  |  |  |                                          optionsProfileUrl, | 
					
						
							|  |  |  |                                          optionsLink).encode() | 
					
						
							| 
									
										
										
										
											2019-08-24 21:14:33 +00:00
										 |  |  |                    self._set_headers('text/html',len(msg),cookie) | 
					
						
							|  |  |  |                    self.wfile.write(msg) | 
					
						
							|  |  |  |                    self.server.GETbusy=False | 
					
						
							|  |  |  |                    return | 
					
						
							|  |  |  |                self._redirect_headers(originPathStr,cookie) | 
					
						
							|  |  |  |                self.server.GETbusy=False | 
					
						
							|  |  |  |                return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-26 09:15:48 +00:00
										 |  |  |         # remove a shared item | 
					
						
							|  |  |  |         if htmlGET and '?rmshare=' in self.path: | 
					
						
							|  |  |  |             shareName=self.path.split('?rmshare=')[1] | 
					
						
							|  |  |  |             actor=self.server.httpPrefix+'://'+self.server.domainFull+self.path.split('?rmshare=')[0] | 
					
						
							|  |  |  |             msg=htmlRemoveSharedItem(self.server.baseDir,actor,shareName).encode() | 
					
						
							|  |  |  |             if not msg: | 
					
						
							|  |  |  |                self._redirect_headers(actor+'/inbox',cookie) | 
					
						
							|  |  |  |                self.server.GETbusy=False | 
					
						
							|  |  |  |                return                 | 
					
						
							|  |  |  |             self._set_headers('text/html',len(msg),cookie) | 
					
						
							|  |  |  |             self.wfile.write(msg) | 
					
						
							|  |  |  |             self.server.GETbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-26 16:07:04 +00:00
										 |  |  |         if self.path.startswith('/terms'): | 
					
						
							|  |  |  |             msg=htmlTermsOfService(self.server.baseDir, \ | 
					
						
							|  |  |  |                                    self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                    self.server.domainFull).encode() | 
					
						
							|  |  |  |             self._login_headers('text/html',len(msg)) | 
					
						
							|  |  |  |             self.wfile.write(msg) | 
					
						
							|  |  |  |             self.server.GETbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if self.path.startswith('/about'): | 
					
						
							|  |  |  |             msg=htmlAbout(self.server.baseDir, \ | 
					
						
							|  |  |  |                           self.server.httpPrefix, \ | 
					
						
							|  |  |  |                           self.server.domainFull).encode() | 
					
						
							|  |  |  |             self._login_headers('text/html',len(msg)) | 
					
						
							|  |  |  |             self.wfile.write(msg) | 
					
						
							|  |  |  |             self.server.GETbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-18 20:11:26 +00:00
										 |  |  |         # if not authorized then show the login screen | 
					
						
							| 
									
										
										
										
											2019-08-26 16:07:04 +00:00
										 |  |  |         if htmlGET and self.path!='/login' and self.path!='/': | 
					
						
							| 
									
										
										
										
											2019-08-18 20:11:26 +00:00
										 |  |  |             if '/media/' not in self.path and \ | 
					
						
							|  |  |  |                '/sharefiles/' not in self.path and \ | 
					
						
							|  |  |  |                '/statuses/' not in self.path and \ | 
					
						
							|  |  |  |                '/emoji/' not in self.path and \ | 
					
						
							|  |  |  |                '/tags/' not in self.path and \ | 
					
						
							|  |  |  |                '/icons/' not in self.path: | 
					
						
							|  |  |  |                 divertToLoginScreen=True | 
					
						
							|  |  |  |                 if self.path.startswith('/users/'): | 
					
						
							|  |  |  |                     nickStr=self.path.split('/users/')[1] | 
					
						
							|  |  |  |                     if '/' not in nickStr and '?' not in nickStr: | 
					
						
							|  |  |  |                         divertToLoginScreen=False | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         if self.path.endswith('/following') or \ | 
					
						
							|  |  |  |                            self.path.endswith('/followers') or \ | 
					
						
							|  |  |  |                            self.path.endswith('/skills') or \ | 
					
						
							|  |  |  |                            self.path.endswith('/roles') or \ | 
					
						
							|  |  |  |                            self.path.endswith('/shares'): | 
					
						
							| 
									
										
										
										
											2019-07-28 13:30:19 +00:00
										 |  |  |                             divertToLoginScreen=False | 
					
						
							| 
									
										
										
										
											2019-08-18 20:11:26 +00:00
										 |  |  |                 if divertToLoginScreen and not authorized: | 
					
						
							|  |  |  |                     if self.server.debug: | 
					
						
							|  |  |  |                         print('DEBUG: divertToLoginScreen='+str(divertToLoginScreen)) | 
					
						
							|  |  |  |                         print('DEBUG: authorized='+str(authorized)) | 
					
						
							| 
									
										
										
										
											2019-08-21 17:05:51 +00:00
										 |  |  |                         print('DEBUG: path='+self.path) | 
					
						
							| 
									
										
										
										
											2019-08-18 20:11:26 +00:00
										 |  |  |                     self.send_response(303) | 
					
						
							|  |  |  |                     self.send_header('Location', '/login') | 
					
						
							|  |  |  |                     self.send_header('Content-Length', '0') | 
					
						
							|  |  |  |                     self.end_headers() | 
					
						
							|  |  |  |                     self.server.GETbusy=False | 
					
						
							|  |  |  |                     return | 
					
						
							| 
									
										
										
										
											2019-07-25 11:18:35 +00:00
										 |  |  |              | 
					
						
							| 
									
										
										
										
											2019-07-21 09:09:28 +00:00
										 |  |  |         # get css | 
					
						
							|  |  |  |         # Note that this comes before the busy flag to avoid conflicts | 
					
						
							|  |  |  |         if self.path.endswith('.css'): | 
					
						
							| 
									
										
										
										
											2019-07-24 11:03:56 +00:00
										 |  |  |             if os.path.isfile('epicyon-profile.css'): | 
					
						
							|  |  |  |                 with open('epicyon-profile.css', 'r') as cssfile: | 
					
						
							| 
									
										
										
										
											2019-07-21 09:09:28 +00:00
										 |  |  |                     css = cssfile.read() | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                 msg=css.encode('utf-8') | 
					
						
							|  |  |  |                 self._set_headers('text/css',len(msg),cookie) | 
					
						
							|  |  |  |                 self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-08-15 11:42:01 +00:00
										 |  |  |                 self.wfile.flush()  | 
					
						
							| 
									
										
										
										
											2019-07-21 09:09:28 +00:00
										 |  |  |                 return | 
					
						
							| 
									
										
										
										
											2019-07-24 22:38:42 +00:00
										 |  |  |         # image on login screen | 
					
						
							|  |  |  |         if self.path=='/login.png': | 
					
						
							|  |  |  |             mediaFilename= \ | 
					
						
							|  |  |  |                 self.server.baseDir+'/accounts/login.png' | 
					
						
							|  |  |  |             if os.path.isfile(mediaFilename): | 
					
						
							|  |  |  |                 with open(mediaFilename, 'rb') as avFile: | 
					
						
							|  |  |  |                     mediaBinary = avFile.read() | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                     self._set_headers('image/png',len(mediaBinary),cookie) | 
					
						
							| 
									
										
										
										
											2019-07-24 22:38:42 +00:00
										 |  |  |                     self.wfile.write(mediaBinary) | 
					
						
							| 
									
										
										
										
											2019-08-15 11:42:01 +00:00
										 |  |  |                     self.wfile.flush()  | 
					
						
							| 
									
										
										
										
											2019-08-16 22:21:34 +00:00
										 |  |  |             self._404() | 
					
						
							| 
									
										
										
										
											2019-07-24 22:38:42 +00:00
										 |  |  |             return         | 
					
						
							| 
									
										
										
										
											2019-07-25 19:56:25 +00:00
										 |  |  |         # login screen background image | 
					
						
							|  |  |  |         if self.path=='/login-background.png': | 
					
						
							|  |  |  |             mediaFilename= \ | 
					
						
							|  |  |  |                 self.server.baseDir+'/accounts/login-background.png' | 
					
						
							|  |  |  |             if os.path.isfile(mediaFilename): | 
					
						
							|  |  |  |                 with open(mediaFilename, 'rb') as avFile: | 
					
						
							|  |  |  |                     mediaBinary = avFile.read() | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                     self._set_headers('image/png',len(mediaBinary),cookie) | 
					
						
							| 
									
										
										
										
											2019-07-25 19:56:25 +00:00
										 |  |  |                     self.wfile.write(mediaBinary) | 
					
						
							| 
									
										
										
										
											2019-08-15 11:42:01 +00:00
										 |  |  |                     self.wfile.flush()  | 
					
						
							| 
									
										
										
										
											2019-08-16 22:21:34 +00:00
										 |  |  |                     return | 
					
						
							|  |  |  |             self._404() | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-07-29 09:49:46 +00:00
										 |  |  |         # follow screen background image | 
					
						
							|  |  |  |         if self.path=='/follow-background.png': | 
					
						
							|  |  |  |             mediaFilename= \ | 
					
						
							|  |  |  |                 self.server.baseDir+'/accounts/follow-background.png' | 
					
						
							|  |  |  |             if os.path.isfile(mediaFilename): | 
					
						
							|  |  |  |                 with open(mediaFilename, 'rb') as avFile: | 
					
						
							|  |  |  |                     mediaBinary = avFile.read() | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                     self._set_headers('image/png',len(mediaBinary),cookie) | 
					
						
							| 
									
										
										
										
											2019-07-29 09:49:46 +00:00
										 |  |  |                     self.wfile.write(mediaBinary) | 
					
						
							| 
									
										
										
										
											2019-08-15 11:42:01 +00:00
										 |  |  |                     self.wfile.flush()  | 
					
						
							| 
									
										
										
										
											2019-08-16 22:21:34 +00:00
										 |  |  |             self._404() | 
					
						
							| 
									
										
										
										
											2019-08-09 12:50:49 +00:00
										 |  |  |             return | 
					
						
							|  |  |  |         # emoji images | 
					
						
							|  |  |  |         if '/emoji/' in self.path: | 
					
						
							|  |  |  |             if self.path.endswith('.png') or \ | 
					
						
							|  |  |  |                self.path.endswith('.jpg') or \ | 
					
						
							|  |  |  |                self.path.endswith('.gif'): | 
					
						
							|  |  |  |                 emojiStr=self.path.split('/emoji/')[1] | 
					
						
							|  |  |  |                 emojiFilename= \ | 
					
						
							|  |  |  |                     self.server.baseDir+'/emoji/'+emojiStr | 
					
						
							|  |  |  |                 if os.path.isfile(emojiFilename): | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                     mediaImageType='png' | 
					
						
							| 
									
										
										
										
											2019-08-09 12:50:49 +00:00
										 |  |  |                     if emojiFilename.endswith('.png'): | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                         mediaImageType='png' | 
					
						
							| 
									
										
										
										
											2019-08-09 12:50:49 +00:00
										 |  |  |                     elif emojiFilename.endswith('.jpg'): | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                         mediaImageType='jpeg' | 
					
						
							| 
									
										
										
										
											2019-08-09 12:50:49 +00:00
										 |  |  |                     else: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                         mediaImageType='gif' | 
					
						
							| 
									
										
										
										
											2019-08-09 12:50:49 +00:00
										 |  |  |                     with open(emojiFilename, 'rb') as avFile: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                         mediaBinary = avFile.read() | 
					
						
							|  |  |  |                         self._set_headers('image/'+mediaImageType,len(mediaBinary),cookie) | 
					
						
							|  |  |  |                         self.wfile.write(mediaBinary) | 
					
						
							| 
									
										
										
										
											2019-08-15 11:42:01 +00:00
										 |  |  |                         self.wfile.flush()  | 
					
						
							| 
									
										
										
										
											2019-08-09 17:42:11 +00:00
										 |  |  |                     return | 
					
						
							| 
									
										
										
										
											2019-08-09 12:50:49 +00:00
										 |  |  |             self._404() | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-07-12 19:33:34 +00:00
										 |  |  |         # show media | 
					
						
							| 
									
										
										
										
											2019-07-22 09:52:43 +00:00
										 |  |  |         # Note that this comes before the busy flag to avoid conflicts | 
					
						
							| 
									
										
										
										
											2019-07-12 19:33:34 +00:00
										 |  |  |         if '/media/' in self.path: | 
					
						
							|  |  |  |             if self.path.endswith('.png') or \ | 
					
						
							|  |  |  |                self.path.endswith('.jpg') or \ | 
					
						
							|  |  |  |                self.path.endswith('.gif'): | 
					
						
							|  |  |  |                 mediaStr=self.path.split('/media/')[1] | 
					
						
							|  |  |  |                 mediaFilename= \ | 
					
						
							|  |  |  |                     self.server.baseDir+'/media/'+mediaStr | 
					
						
							|  |  |  |                 if os.path.isfile(mediaFilename): | 
					
						
							| 
									
										
										
										
											2019-08-15 12:22:34 +00:00
										 |  |  |                     mediaFileType='png' | 
					
						
							| 
									
										
										
										
											2019-07-12 19:33:34 +00:00
										 |  |  |                     if mediaFilename.endswith('.png'): | 
					
						
							| 
									
										
										
										
											2019-08-15 12:22:34 +00:00
										 |  |  |                         mediaFileType='png' | 
					
						
							| 
									
										
										
										
											2019-07-12 19:33:34 +00:00
										 |  |  |                     elif mediaFilename.endswith('.jpg'): | 
					
						
							| 
									
										
										
										
											2019-08-15 12:22:34 +00:00
										 |  |  |                         mediaFileType='jepg' | 
					
						
							| 
									
										
										
										
											2019-07-12 19:33:34 +00:00
										 |  |  |                     else: | 
					
						
							| 
									
										
										
										
											2019-08-15 12:22:34 +00:00
										 |  |  |                         mediaFileType='gif' | 
					
						
							| 
									
										
										
										
											2019-07-12 19:33:34 +00:00
										 |  |  |                     with open(mediaFilename, 'rb') as avFile: | 
					
						
							|  |  |  |                         mediaBinary = avFile.read() | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                         self._set_headers('image/'+mediaFileType,len(mediaBinary),cookie) | 
					
						
							| 
									
										
										
										
											2019-07-12 19:33:34 +00:00
										 |  |  |                         self.wfile.write(mediaBinary) | 
					
						
							| 
									
										
										
										
											2019-08-15 11:42:01 +00:00
										 |  |  |                         self.wfile.flush()  | 
					
						
							| 
									
										
										
										
											2019-07-12 19:33:34 +00:00
										 |  |  |                     return         | 
					
						
							| 
									
										
										
										
											2019-07-16 16:10:52 +00:00
										 |  |  |             self._404() | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-07-23 12:33:09 +00:00
										 |  |  |         # show shared item images | 
					
						
							|  |  |  |         # Note that this comes before the busy flag to avoid conflicts | 
					
						
							|  |  |  |         if '/sharefiles/' in self.path: | 
					
						
							|  |  |  |             if self.path.endswith('.png') or \ | 
					
						
							|  |  |  |                self.path.endswith('.jpg') or \ | 
					
						
							|  |  |  |                self.path.endswith('.gif'): | 
					
						
							|  |  |  |                 mediaStr=self.path.split('/sharefiles/')[1] | 
					
						
							|  |  |  |                 mediaFilename= \ | 
					
						
							|  |  |  |                     self.server.baseDir+'/sharefiles/'+mediaStr | 
					
						
							|  |  |  |                 if os.path.isfile(mediaFilename): | 
					
						
							| 
									
										
										
										
											2019-08-15 12:22:34 +00:00
										 |  |  |                     mediaFileType='png' | 
					
						
							| 
									
										
										
										
											2019-07-23 12:33:09 +00:00
										 |  |  |                     if mediaFilename.endswith('.png'): | 
					
						
							| 
									
										
										
										
											2019-08-15 12:22:34 +00:00
										 |  |  |                         mediaFileType='png' | 
					
						
							| 
									
										
										
										
											2019-07-23 12:33:09 +00:00
										 |  |  |                     elif mediaFilename.endswith('.jpg'): | 
					
						
							| 
									
										
										
										
											2019-08-15 12:22:34 +00:00
										 |  |  |                         mediaFileType='jpeg' | 
					
						
							| 
									
										
										
										
											2019-07-23 12:33:09 +00:00
										 |  |  |                     else: | 
					
						
							| 
									
										
										
										
											2019-08-15 12:22:34 +00:00
										 |  |  |                         mediaFileType='gif' | 
					
						
							| 
									
										
										
										
											2019-07-23 12:33:09 +00:00
										 |  |  |                     with open(mediaFilename, 'rb') as avFile: | 
					
						
							|  |  |  |                         mediaBinary = avFile.read() | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                         self._set_headers('image/'+mediaFileType,len(mediaBinary),cookie) | 
					
						
							| 
									
										
										
										
											2019-07-23 12:33:09 +00:00
										 |  |  |                         self.wfile.write(mediaBinary) | 
					
						
							| 
									
										
										
										
											2019-08-15 11:42:01 +00:00
										 |  |  |                         self.wfile.flush()  | 
					
						
							| 
									
										
										
										
											2019-07-23 12:33:09 +00:00
										 |  |  |                     return         | 
					
						
							|  |  |  |             self._404() | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-07-26 10:30:13 +00:00
										 |  |  |         # icon images | 
					
						
							|  |  |  |         # Note that this comes before the busy flag to avoid conflicts | 
					
						
							| 
									
										
										
										
											2019-07-26 12:26:41 +00:00
										 |  |  |         if self.path.startswith('/icons/'): | 
					
						
							| 
									
										
										
										
											2019-07-26 10:30:13 +00:00
										 |  |  |             if self.path.endswith('.png'): | 
					
						
							|  |  |  |                 mediaStr=self.path.split('/icons/')[1] | 
					
						
							|  |  |  |                 mediaFilename= \ | 
					
						
							|  |  |  |                     self.server.baseDir+'/img/icons/'+mediaStr | 
					
						
							|  |  |  |                 if os.path.isfile(mediaFilename): | 
					
						
							|  |  |  |                     if mediaFilename.endswith('.png'): | 
					
						
							|  |  |  |                         with open(mediaFilename, 'rb') as avFile: | 
					
						
							|  |  |  |                             mediaBinary = avFile.read() | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                             self._set_headers('image/png',len(mediaBinary),cookie) | 
					
						
							| 
									
										
										
										
											2019-07-26 10:30:13 +00:00
										 |  |  |                             self.wfile.write(mediaBinary) | 
					
						
							| 
									
										
										
										
											2019-08-15 11:42:01 +00:00
										 |  |  |                             self.wfile.flush()  | 
					
						
							| 
									
										
										
										
											2019-07-26 10:30:13 +00:00
										 |  |  |                         return         | 
					
						
							|  |  |  |             self._404() | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-07-12 16:09:25 +00:00
										 |  |  |         # show avatar or background image | 
					
						
							| 
									
										
										
										
											2019-07-22 09:52:43 +00:00
										 |  |  |         # Note that this comes before the busy flag to avoid conflicts | 
					
						
							| 
									
										
										
										
											2019-07-12 16:03:01 +00:00
										 |  |  |         if '/users/' in self.path: | 
					
						
							|  |  |  |             if self.path.endswith('.png') or \ | 
					
						
							|  |  |  |                self.path.endswith('.jpg') or \ | 
					
						
							|  |  |  |                self.path.endswith('.gif'): | 
					
						
							|  |  |  |                 avatarStr=self.path.split('/users/')[1] | 
					
						
							|  |  |  |                 if '/' in avatarStr: | 
					
						
							|  |  |  |                     avatarNickname=avatarStr.split('/')[0] | 
					
						
							|  |  |  |                     avatarFile=avatarStr.split('/')[1] | 
					
						
							|  |  |  |                     avatarFilename= \ | 
					
						
							|  |  |  |                         self.server.baseDir+'/accounts/'+ \ | 
					
						
							|  |  |  |                         avatarNickname+'@'+ \ | 
					
						
							|  |  |  |                         self.server.domain+'/'+avatarFile | 
					
						
							|  |  |  |                     if os.path.isfile(avatarFilename): | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                         mediaImageType='png' | 
					
						
							| 
									
										
										
										
											2019-07-12 16:03:01 +00:00
										 |  |  |                         if avatarFile.endswith('.png'): | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                             mediaImageType='png' | 
					
						
							| 
									
										
										
										
											2019-07-12 16:03:01 +00:00
										 |  |  |                         elif avatarFile.endswith('.jpg'): | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                             mediaImageType='jpeg' | 
					
						
							| 
									
										
										
										
											2019-07-12 16:03:01 +00:00
										 |  |  |                         else: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                             mediaImageType='gif' | 
					
						
							| 
									
										
										
										
											2019-07-12 16:03:01 +00:00
										 |  |  |                         with open(avatarFilename, 'rb') as avFile: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                             mediaBinary = avFile.read() | 
					
						
							|  |  |  |                             self._set_headers('image/'+mediaImageType,len(mediaBinary),cookie) | 
					
						
							|  |  |  |                             self.wfile.write(mediaBinary) | 
					
						
							| 
									
										
										
										
											2019-08-15 11:42:01 +00:00
										 |  |  |                             self.wfile.flush()  | 
					
						
							| 
									
										
										
										
											2019-07-22 15:14:39 +00:00
										 |  |  |                         return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # This busy state helps to avoid flooding | 
					
						
							|  |  |  |         # Resources which are expected to be called from a web page | 
					
						
							|  |  |  |         # should be above this | 
					
						
							| 
									
										
										
										
											2019-07-22 09:52:43 +00:00
										 |  |  |         if self.server.GETbusy: | 
					
						
							|  |  |  |             currTimeGET=int(time.time()) | 
					
						
							| 
									
										
										
										
											2019-08-14 22:24:51 +00:00
										 |  |  |             if currTimeGET-self.server.lastGET==0: | 
					
						
							| 
									
										
										
										
											2019-07-22 09:52:43 +00:00
										 |  |  |                 if self.server.debug: | 
					
						
							|  |  |  |                     print('DEBUG: GET Busy') | 
					
						
							| 
									
										
										
										
											2019-07-25 16:50:48 +00:00
										 |  |  |                 self.send_response(429)                     | 
					
						
							| 
									
										
										
										
											2019-07-22 09:52:43 +00:00
										 |  |  |                 self.end_headers() | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  |             self.server.lastGET=currTimeGET | 
					
						
							|  |  |  |         self.server.GETbusy=True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if not self._permittedDir(self.path): | 
					
						
							|  |  |  |             if self.server.debug: | 
					
						
							|  |  |  |                 print('DEBUG: GET Not permitted') | 
					
						
							|  |  |  |             self._404() | 
					
						
							|  |  |  |             self.server.GETbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         # get webfinger endpoint for a person | 
					
						
							| 
									
										
										
										
											2019-07-25 14:24:42 +00:00
										 |  |  |         if self._webfinger(): | 
					
						
							| 
									
										
										
										
											2019-07-22 09:52:43 +00:00
										 |  |  |             self.server.GETbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-08-08 13:38:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-15 13:40:27 +00:00
										 |  |  |         if self.path.startswith('/login') or self.path=='/': | 
					
						
							| 
									
										
										
										
											2019-07-24 22:38:42 +00:00
										 |  |  |             # request basic auth | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |             msg=htmlLogin(self.server.baseDir).encode('utf-8') | 
					
						
							|  |  |  |             self._login_headers('text/html',len(msg)) | 
					
						
							|  |  |  |             self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-07-24 22:38:42 +00:00
										 |  |  |             self.server.GETbusy=False | 
					
						
							| 
									
										
										
										
											2019-07-25 21:39:09 +00:00
										 |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-10 10:54:52 +00:00
										 |  |  |         # hashtag search | 
					
						
							|  |  |  |         if self.path.startswith('/tags/'): | 
					
						
							|  |  |  |             pageNumber=1 | 
					
						
							|  |  |  |             if '?page=' in self.path: | 
					
						
							|  |  |  |                 pageNumberStr=self.path.split('?page=')[1] | 
					
						
							|  |  |  |                 if pageNumberStr.isdigit(): | 
					
						
							|  |  |  |                     pageNumber=int(pageNumberStr) | 
					
						
							|  |  |  |             hashtag=self.path.split('/tags/')[1] | 
					
						
							|  |  |  |             if '?page=' in hashtag: | 
					
						
							|  |  |  |                 hashtag=hashtag.split('?page=')[0] | 
					
						
							| 
									
										
										
										
											2019-08-14 10:32:15 +00:00
										 |  |  |             if isBlockedHashtag(self.server.baseDir,hashtag): | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                 msg=htmlHashtagBlocked(self.server.baseDir).encode('utf-8') | 
					
						
							|  |  |  |                 self._login_headers('text/html',len(msg)) | 
					
						
							|  |  |  |                 self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-08-14 10:32:15 +00:00
										 |  |  |                 self.server.GETbusy=False | 
					
						
							|  |  |  |                 return | 
					
						
							| 
									
										
										
										
											2019-08-10 10:54:52 +00:00
										 |  |  |             hashtagStr= \ | 
					
						
							|  |  |  |                 htmlHashtagSearch(self.server.baseDir,hashtag,pageNumber, \ | 
					
						
							|  |  |  |                                   maxPostsInFeed,self.server.session, \ | 
					
						
							|  |  |  |                                   self.server.cachedWebfingers, \ | 
					
						
							| 
									
										
										
										
											2019-08-14 20:12:27 +00:00
										 |  |  |                                   self.server.personCache, \ | 
					
						
							|  |  |  |                                   self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                   self.server.projectVersion) | 
					
						
							| 
									
										
										
										
											2019-08-10 10:54:52 +00:00
										 |  |  |             if hashtagStr: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                 msg=hashtagStr.encode() | 
					
						
							|  |  |  |                 self._set_headers('text/html',len(msg),cookie) | 
					
						
							|  |  |  |                 self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-08-10 10:54:52 +00:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                 originPathStr=self.path.split('/tags/')[0] | 
					
						
							|  |  |  |                 self._redirect_headers(originPathStr+'/search',cookie)                 | 
					
						
							| 
									
										
										
										
											2019-08-10 10:54:52 +00:00
										 |  |  |             self.server.GETbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-19 20:01:29 +00:00
										 |  |  |         # search for a fediverse address, shared item or emoji from the web interface by selecting search icon | 
					
						
							| 
									
										
										
										
											2019-08-18 20:11:26 +00:00
										 |  |  |         if htmlGET and '/users/' in self.path: | 
					
						
							| 
									
										
										
										
											2019-07-30 22:34:04 +00:00
										 |  |  |            if self.path.endswith('/search'): | 
					
						
							|  |  |  |                # show the search screen | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                msg=htmlSearch(self.server.baseDir,self.path).encode() | 
					
						
							|  |  |  |                self._set_headers('text/html',len(msg),cookie) | 
					
						
							|  |  |  |                self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-07-30 22:34:04 +00:00
										 |  |  |                self.server.GETbusy=False | 
					
						
							|  |  |  |                return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-19 20:01:29 +00:00
										 |  |  |         # search for emoji by name | 
					
						
							|  |  |  |         if htmlGET and '/users/' in self.path: | 
					
						
							|  |  |  |            if self.path.endswith('/searchemoji'): | 
					
						
							|  |  |  |                # show the search screen | 
					
						
							|  |  |  |                msg=htmlSearchEmojiTextEntry(self.server.baseDir,self.path).encode() | 
					
						
							|  |  |  |                self._set_headers('text/html',len(msg),cookie) | 
					
						
							|  |  |  |                self.wfile.write(msg) | 
					
						
							|  |  |  |                self.server.GETbusy=False | 
					
						
							|  |  |  |                return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-01 09:05:09 +00:00
										 |  |  |         # announce/repeat from the web interface | 
					
						
							| 
									
										
										
										
											2019-08-18 20:11:26 +00:00
										 |  |  |         if htmlGET and '?repeat=' in self.path: | 
					
						
							| 
									
										
										
										
											2019-07-31 16:47:45 +00:00
										 |  |  |             repeatUrl=self.path.split('?repeat=')[1] | 
					
						
							|  |  |  |             actor=self.path.split('?repeat=')[0] | 
					
						
							|  |  |  |             self.postToNickname=getNicknameFromActor(actor) | 
					
						
							|  |  |  |             if not self.server.session: | 
					
						
							|  |  |  |                 self.server.session= \ | 
					
						
							|  |  |  |                     createSession(self.server.domain,self.server.port,self.server.useTor)                 | 
					
						
							|  |  |  |             announceJson= \ | 
					
						
							|  |  |  |                 createAnnounce(self.server.session, \ | 
					
						
							|  |  |  |                                self.server.baseDir, \ | 
					
						
							|  |  |  |                                self.server.federationList, \ | 
					
						
							|  |  |  |                                self.postToNickname, \ | 
					
						
							|  |  |  |                                self.server.domain,self.server.port, \ | 
					
						
							|  |  |  |                                'https://www.w3.org/ns/activitystreams#Public', \ | 
					
						
							|  |  |  |                                None,self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                repeatUrl,False,False, \ | 
					
						
							|  |  |  |                                self.server.sendThreads, \ | 
					
						
							|  |  |  |                                self.server.postLog, \ | 
					
						
							|  |  |  |                                self.server.personCache, \ | 
					
						
							|  |  |  |                                self.server.cachedWebfingers, \ | 
					
						
							| 
									
										
										
										
											2019-08-14 20:12:27 +00:00
										 |  |  |                                self.server.debug, \ | 
					
						
							|  |  |  |                                self.server.projectVersion) | 
					
						
							| 
									
										
										
										
											2019-07-31 16:47:45 +00:00
										 |  |  |             if announceJson: | 
					
						
							|  |  |  |                 self._postToOutbox(announceJson) | 
					
						
							|  |  |  |             self.server.GETbusy=False | 
					
						
							| 
									
										
										
										
											2019-07-31 19:37:29 +00:00
										 |  |  |             self._redirect_headers(actor+'/inbox',cookie) | 
					
						
							| 
									
										
										
										
											2019-07-31 16:47:45 +00:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-08-01 09:05:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-01 12:18:22 +00:00
										 |  |  |         # undo an announce/repeat from the web interface | 
					
						
							| 
									
										
										
										
											2019-08-18 20:11:26 +00:00
										 |  |  |         if htmlGET and '?unrepeat=' in self.path: | 
					
						
							| 
									
										
										
										
											2019-08-01 12:18:22 +00:00
										 |  |  |             repeatUrl=self.path.split('?unrepeat=')[1] | 
					
						
							|  |  |  |             actor=self.path.split('?unrepeat=')[0] | 
					
						
							|  |  |  |             self.postToNickname=getNicknameFromActor(actor) | 
					
						
							|  |  |  |             if not self.server.session: | 
					
						
							|  |  |  |                 self.server.session= \ | 
					
						
							|  |  |  |                     createSession(self.server.domain,self.server.port,self.server.useTor) | 
					
						
							|  |  |  |             undoAnnounceActor=self.server.httpPrefix+'://'+self.server.domainFull+'/users/'+self.postToNickname | 
					
						
							|  |  |  |             newUndoAnnounce = { | 
					
						
							| 
									
										
										
										
											2019-08-18 11:07:06 +00:00
										 |  |  |                 "@context": "https://www.w3.org/ns/activitystreams", | 
					
						
							| 
									
										
										
										
											2019-08-01 12:18:22 +00:00
										 |  |  |                 'actor': undoAnnounceActor, | 
					
						
							|  |  |  |                 'type': 'Undo', | 
					
						
							|  |  |  |                 'cc': [undoAnnounceActor+'/followers'], | 
					
						
							|  |  |  |                 'to': ['https://www.w3.org/ns/activitystreams#Public'], | 
					
						
							|  |  |  |                 'object': { | 
					
						
							|  |  |  |                     'actor': undoAnnounceActor, | 
					
						
							|  |  |  |                     'cc': [undoAnnounceActor+'/followers'], | 
					
						
							|  |  |  |                     'object': repeatUrl, | 
					
						
							|  |  |  |                     'to': ['https://www.w3.org/ns/activitystreams#Public'], | 
					
						
							|  |  |  |                     'type': 'Announce' | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             }                 | 
					
						
							|  |  |  |             self._postToOutbox(newUndoAnnounce) | 
					
						
							|  |  |  |             self.server.GETbusy=False | 
					
						
							|  |  |  |             self._redirect_headers(actor+'/inbox',cookie) | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-07 11:58:01 +00:00
										 |  |  |         # send a follow request approval from the web interface | 
					
						
							| 
									
										
										
										
											2019-08-07 14:08:32 +00:00
										 |  |  |         if authorized and '/followapprove=' in self.path and self.path.startswith('/users/'): | 
					
						
							| 
									
										
										
										
											2019-08-07 11:57:14 +00:00
										 |  |  |             originPathStr=self.path.split('/followapprove=')[0] | 
					
						
							| 
									
										
										
										
											2019-08-07 14:08:32 +00:00
										 |  |  |             followerNickname=originPathStr.replace('/users/','') | 
					
						
							| 
									
										
										
										
											2019-08-07 11:57:14 +00:00
										 |  |  |             followingHandle=self.path.split('/followapprove=')[1] | 
					
						
							|  |  |  |             if '@' in followingHandle: | 
					
						
							| 
									
										
										
										
											2019-08-07 12:50:48 +00:00
										 |  |  |                 if not self.server.session: | 
					
						
							|  |  |  |                     self.server.session= \ | 
					
						
							|  |  |  |                         createSession(self.server.domain,self.server.port,self.server.useTor) | 
					
						
							| 
									
										
										
										
											2019-08-07 11:57:14 +00:00
										 |  |  |                 manualApproveFollowRequest(self.server.session, \ | 
					
						
							|  |  |  |                                            self.server.baseDir, \ | 
					
						
							|  |  |  |                                            self.server.httpPrefix, \ | 
					
						
							| 
									
										
										
										
											2019-08-07 14:08:32 +00:00
										 |  |  |                                            followerNickname,self.server.domain,self.server.port, \ | 
					
						
							| 
									
										
										
										
											2019-08-07 11:57:14 +00:00
										 |  |  |                                            followingHandle, \ | 
					
						
							|  |  |  |                                            self.server.federationList, \ | 
					
						
							|  |  |  |                                            self.server.sendThreads, \ | 
					
						
							|  |  |  |                                            self.server.postLog, \ | 
					
						
							|  |  |  |                                            self.server.cachedWebfingers, \ | 
					
						
							|  |  |  |                                            self.server.personCache, \ | 
					
						
							|  |  |  |                                            self.server.acceptedCaps, \ | 
					
						
							| 
									
										
										
										
											2019-08-14 20:12:27 +00:00
										 |  |  |                                            self.server.debug, \ | 
					
						
							|  |  |  |                                            self.server.projectVersion) | 
					
						
							| 
									
										
										
										
											2019-08-07 11:57:14 +00:00
										 |  |  |             self._redirect_headers(originPathStr,cookie) | 
					
						
							|  |  |  |             self.server.GETbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-07 11:58:01 +00:00
										 |  |  |         # deny a follow request from the web interface | 
					
						
							| 
									
										
										
										
											2019-08-07 14:08:32 +00:00
										 |  |  |         if authorized and '/followdeny=' in self.path and self.path.startswith('/users/'): | 
					
						
							| 
									
										
										
										
											2019-08-07 11:57:14 +00:00
										 |  |  |             originPathStr=self.path.split('/followdeny=')[0] | 
					
						
							| 
									
										
										
										
											2019-08-07 14:08:32 +00:00
										 |  |  |             followerNickname=originPathStr.replace('/users/','') | 
					
						
							| 
									
										
										
										
											2019-08-07 11:57:14 +00:00
										 |  |  |             followingHandle=self.path.split('/followdeny=')[1] | 
					
						
							|  |  |  |             if '@' in followingHandle: | 
					
						
							|  |  |  |                 manualDenyFollowRequest(self.server.baseDir, \ | 
					
						
							| 
									
										
										
										
											2019-08-07 14:08:32 +00:00
										 |  |  |                                         followerNickname,self.server.domain, \ | 
					
						
							| 
									
										
										
										
											2019-08-07 11:57:14 +00:00
										 |  |  |                                         followingHandle) | 
					
						
							|  |  |  |             self._redirect_headers(originPathStr,cookie) | 
					
						
							|  |  |  |             self.server.GETbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-01 09:05:09 +00:00
										 |  |  |         # like from the web interface icon | 
					
						
							| 
									
										
										
										
											2019-08-18 20:11:26 +00:00
										 |  |  |         if htmlGET and '?like=' in self.path and '/statuses/' in self.path: | 
					
						
							| 
									
										
										
										
											2019-08-01 09:05:09 +00:00
										 |  |  |             likeUrl=self.path.split('?like=')[1] | 
					
						
							|  |  |  |             actor=self.path.split('?like=')[0] | 
					
						
							|  |  |  |             self.postToNickname=getNicknameFromActor(actor) | 
					
						
							|  |  |  |             if not self.server.session: | 
					
						
							|  |  |  |                 self.server.session= \ | 
					
						
							|  |  |  |                     createSession(self.server.domain,self.server.port,self.server.useTor) | 
					
						
							| 
									
										
										
										
											2019-08-01 12:49:16 +00:00
										 |  |  |             likeActor=self.server.httpPrefix+'://'+self.server.domainFull+'/users/'+self.postToNickname | 
					
						
							| 
									
										
										
										
											2019-08-07 11:05:13 +00:00
										 |  |  |             actorLiked=likeUrl.split('/statuses/')[0] | 
					
						
							| 
									
										
										
										
											2019-08-01 09:05:09 +00:00
										 |  |  |             likeJson= { | 
					
						
							| 
									
										
										
										
											2019-08-18 11:07:06 +00:00
										 |  |  |                 "@context": "https://www.w3.org/ns/activitystreams", | 
					
						
							| 
									
										
										
										
											2019-08-01 09:05:09 +00:00
										 |  |  |                 'type': 'Like', | 
					
						
							|  |  |  |                 'actor': likeActor, | 
					
						
							| 
									
										
										
										
											2019-08-18 16:58:50 +00:00
										 |  |  |                 'object': likeUrl | 
					
						
							| 
									
										
										
										
											2019-08-01 09:05:09 +00:00
										 |  |  |             }     | 
					
						
							| 
									
										
										
										
											2019-08-04 18:29:26 +00:00
										 |  |  |             self._postToOutbox(likeJson) | 
					
						
							| 
									
										
										
										
											2019-08-01 09:05:09 +00:00
										 |  |  |             self.server.GETbusy=False | 
					
						
							|  |  |  |             self._redirect_headers(actor+'/inbox',cookie) | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # undo a like from the web interface icon | 
					
						
							| 
									
										
										
										
											2019-08-18 20:11:26 +00:00
										 |  |  |         if htmlGET and '?unlike=' in self.path and '/statuses/' in self.path: | 
					
						
							| 
									
										
										
										
											2019-08-01 09:05:09 +00:00
										 |  |  |             likeUrl=self.path.split('?unlike=')[1] | 
					
						
							|  |  |  |             actor=self.path.split('?unlike=')[0] | 
					
						
							|  |  |  |             self.postToNickname=getNicknameFromActor(actor) | 
					
						
							|  |  |  |             if not self.server.session: | 
					
						
							|  |  |  |                 self.server.session= \ | 
					
						
							|  |  |  |                     createSession(self.server.domain,self.server.port,self.server.useTor) | 
					
						
							| 
									
										
										
										
											2019-08-01 12:49:16 +00:00
										 |  |  |             undoActor=self.server.httpPrefix+'://'+self.server.domainFull+'/users/'+self.postToNickname | 
					
						
							| 
									
										
										
										
											2019-08-07 11:05:13 +00:00
										 |  |  |             actorLiked=likeUrl.split('/statuses/')[0] | 
					
						
							| 
									
										
										
										
											2019-08-01 09:05:09 +00:00
										 |  |  |             undoLikeJson= { | 
					
						
							| 
									
										
										
										
											2019-08-18 11:07:06 +00:00
										 |  |  |                 "@context": "https://www.w3.org/ns/activitystreams", | 
					
						
							| 
									
										
										
										
											2019-08-01 09:05:09 +00:00
										 |  |  |                 'type': 'Undo', | 
					
						
							|  |  |  |                 'actor': undoActor, | 
					
						
							|  |  |  |                 'object': { | 
					
						
							|  |  |  |                     'type': 'Like', | 
					
						
							|  |  |  |                     'actor': undoActor, | 
					
						
							| 
									
										
										
										
											2019-08-18 16:58:50 +00:00
										 |  |  |                     'object': likeUrl | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2019-08-01 12:49:16 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-08-04 18:29:26 +00:00
										 |  |  |             self._postToOutbox(undoLikeJson) | 
					
						
							|  |  |  |             self.server.GETbusy=False | 
					
						
							|  |  |  |             self._redirect_headers(actor+'/inbox',cookie) | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # delete a post from the web interface icon | 
					
						
							| 
									
										
										
										
											2019-08-18 20:11:26 +00:00
										 |  |  |         if htmlGET and '?delete=' in self.path: | 
					
						
							| 
									
										
										
										
											2019-08-04 18:29:26 +00:00
										 |  |  |             deleteUrl=self.path.split('?delete=')[1] | 
					
						
							| 
									
										
										
										
											2019-08-09 22:49:44 +00:00
										 |  |  |             actor=self.server.httpPrefix+'://'+self.server.domainFull+self.path.split('?delete=')[0] | 
					
						
							| 
									
										
										
										
											2019-08-12 18:02:29 +00:00
										 |  |  |             if self.server.allowDeletion or \ | 
					
						
							|  |  |  |                deleteUrl.startswith(actor): | 
					
						
							|  |  |  |                 if self.server.debug: | 
					
						
							|  |  |  |                     print('DEBUG: deleteUrl='+deleteUrl) | 
					
						
							|  |  |  |                     print('DEBUG: actor='+actor) | 
					
						
							|  |  |  |                 if actor not in deleteUrl: | 
					
						
							|  |  |  |                     # You can only delete your own posts | 
					
						
							|  |  |  |                     self.server.GETbusy=False | 
					
						
							|  |  |  |                     self._redirect_headers(actor+'/inbox',cookie) | 
					
						
							|  |  |  |                     return | 
					
						
							|  |  |  |                 self.postToNickname=getNicknameFromActor(actor) | 
					
						
							|  |  |  |                 if not self.server.session: | 
					
						
							|  |  |  |                     self.server.session= \ | 
					
						
							| 
									
										
										
										
											2019-08-27 12:47:11 +00:00
										 |  |  |                         createSession(self.server.domain,self.server.port, \ | 
					
						
							|  |  |  |                                       self.server.useTor) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 deleteStr= \ | 
					
						
							|  |  |  |                     htmlDeletePost(self.server.session,self.server.baseDir, \ | 
					
						
							|  |  |  |                                    deleteUrl,self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                    __version__,self.server.cachedWebfingers, \ | 
					
						
							|  |  |  |                                    self.server.personCache) | 
					
						
							|  |  |  |                 if deleteStr: | 
					
						
							|  |  |  |                     self._set_headers('text/html',len(deleteStr),cookie) | 
					
						
							| 
									
										
										
										
											2019-08-27 12:52:47 +00:00
										 |  |  |                     self.wfile.write(deleteStr.encode()) | 
					
						
							| 
									
										
										
										
											2019-08-27 12:47:11 +00:00
										 |  |  |                     self.server.GETbusy=False | 
					
						
							|  |  |  |                     return | 
					
						
							| 
									
										
										
										
											2019-08-01 09:05:09 +00:00
										 |  |  |             self.server.GETbusy=False | 
					
						
							|  |  |  |             self._redirect_headers(actor+'/inbox',cookie) | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # reply from the web interface icon | 
					
						
							| 
									
										
										
										
											2019-08-05 17:04:43 +00:00
										 |  |  |         inReplyToUrl=None | 
					
						
							| 
									
										
										
										
											2019-08-12 14:48:19 +00:00
										 |  |  |         replyWithDM=False | 
					
						
							| 
									
										
										
										
											2019-08-05 19:13:15 +00:00
										 |  |  |         replyToList=[] | 
					
						
							| 
									
										
										
										
											2019-08-18 20:11:26 +00:00
										 |  |  |         if htmlGET and '?replyto=' in self.path: | 
					
						
							| 
									
										
										
										
											2019-08-05 17:04:43 +00:00
										 |  |  |             inReplyToUrl=self.path.split('?replyto=')[1] | 
					
						
							| 
									
										
										
										
											2019-08-05 19:13:15 +00:00
										 |  |  |             if '?' in inReplyToUrl: | 
					
						
							|  |  |  |                 mentionsList=inReplyToUrl.split('?') | 
					
						
							|  |  |  |                 for m in mentionsList: | 
					
						
							|  |  |  |                     if m.startswith('mention='): | 
					
						
							|  |  |  |                         replyToList.append(m.replace('mention=','')) | 
					
						
							|  |  |  |                 inReplyToUrl=mentionsList[0] | 
					
						
							| 
									
										
										
										
											2019-07-31 13:51:10 +00:00
										 |  |  |             self.path=self.path.split('?replyto=')[0]+'/newpost' | 
					
						
							| 
									
										
										
										
											2019-08-18 16:06:39 +00:00
										 |  |  |             if self.server.debug: | 
					
						
							|  |  |  |                 print('DEBUG: replyto path '+self.path) | 
					
						
							| 
									
										
										
										
											2019-07-31 13:51:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-12 14:48:19 +00:00
										 |  |  |         # replying as a direct message, for moderation posts | 
					
						
							| 
									
										
										
										
											2019-08-25 22:12:47 +00:00
										 |  |  |         shareDescription=None | 
					
						
							| 
									
										
										
										
											2019-08-18 20:11:26 +00:00
										 |  |  |         if htmlGET and '?replydm=' in self.path: | 
					
						
							| 
									
										
										
										
											2019-08-12 14:48:19 +00:00
										 |  |  |             inReplyToUrl=self.path.split('?replydm=')[1] | 
					
						
							|  |  |  |             if '?' in inReplyToUrl: | 
					
						
							|  |  |  |                 mentionsList=inReplyToUrl.split('?') | 
					
						
							|  |  |  |                 for m in mentionsList: | 
					
						
							|  |  |  |                     if m.startswith('mention='): | 
					
						
							|  |  |  |                         replyToList.append(m.replace('mention=','')) | 
					
						
							|  |  |  |                 inReplyToUrl=mentionsList[0] | 
					
						
							| 
									
										
										
										
											2019-08-25 22:16:05 +00:00
										 |  |  |                 if inReplyToUrl.startswith('sharedesc:'): | 
					
						
							|  |  |  |                     shareDescription=inReplyToUrl.replace('sharedesc:','').replace('%20',' ').replace('%40','@').replace('%3A',':').replace('%23','#') | 
					
						
							| 
									
										
										
										
											2019-08-12 14:48:19 +00:00
										 |  |  |             self.path=self.path.split('?replydm=')[0]+'/newdm' | 
					
						
							| 
									
										
										
										
											2019-08-18 16:06:39 +00:00
										 |  |  |             if self.server.debug: | 
					
						
							|  |  |  |                 print('DEBUG: replydm path '+self.path) | 
					
						
							| 
									
										
										
										
											2019-08-12 14:48:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-02 09:52:12 +00:00
										 |  |  |         # edit profile in web interface | 
					
						
							| 
									
										
										
										
											2019-08-18 20:11:26 +00:00
										 |  |  |         if htmlGET and '/users/' in self.path and self.path.endswith('/editprofile'): | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |             msg=htmlEditProfile(self.server.baseDir,self.path,self.server.domain,self.server.port).encode() | 
					
						
							|  |  |  |             self._set_headers('text/html',len(msg),cookie) | 
					
						
							|  |  |  |             self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-08-02 09:52:12 +00:00
										 |  |  |             self.server.GETbusy=False | 
					
						
							|  |  |  |             return         | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Various types of new post in the web interface | 
					
						
							| 
									
										
										
										
											2019-08-18 20:11:26 +00:00
										 |  |  |         if htmlGET and '/users/' in self.path and \ | 
					
						
							| 
									
										
										
										
											2019-07-26 12:26:41 +00:00
										 |  |  |            (self.path.endswith('/newpost') or \ | 
					
						
							|  |  |  |             self.path.endswith('/newunlisted') or \ | 
					
						
							|  |  |  |             self.path.endswith('/newfollowers') or \ | 
					
						
							|  |  |  |             self.path.endswith('/newdm') or \ | 
					
						
							| 
									
										
										
										
											2019-08-11 11:25:27 +00:00
										 |  |  |             self.path.endswith('/newreport') or \ | 
					
						
							| 
									
										
										
										
											2019-07-26 12:26:41 +00:00
										 |  |  |             self.path.endswith('/newshare')): | 
					
						
							| 
									
										
										
										
											2019-08-25 22:12:47 +00:00
										 |  |  |             msg=htmlNewPost(self.server.baseDir,self.path,inReplyToUrl,replyToList,shareDescription).encode() | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |             self._set_headers('text/html',len(msg),cookie) | 
					
						
							|  |  |  |             self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-07-25 21:39:09 +00:00
										 |  |  |             self.server.GETbusy=False | 
					
						
							| 
									
										
										
										
											2019-08-24 12:38:36 +00:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-07-24 22:38:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-06 21:33:46 +00:00
										 |  |  |         # get an individual post from the path /@nickname/statusnumber | 
					
						
							|  |  |  |         if '/@' in self.path: | 
					
						
							|  |  |  |             namedStatus=self.path.split('/@')[1] | 
					
						
							| 
									
										
										
										
											2019-07-19 13:32:58 +00:00
										 |  |  |             if '/' not in namedStatus: | 
					
						
							|  |  |  |                 # show actor | 
					
						
							|  |  |  |                 nickname=namedStatus | 
					
						
							|  |  |  |             else: | 
					
						
							| 
									
										
										
										
											2019-07-06 21:33:46 +00:00
										 |  |  |                 postSections=namedStatus.split('/') | 
					
						
							|  |  |  |                 if len(postSections)==2: | 
					
						
							|  |  |  |                     nickname=postSections[0] | 
					
						
							|  |  |  |                     statusNumber=postSections[1] | 
					
						
							|  |  |  |                     if len(statusNumber)>10 and statusNumber.isdigit(): | 
					
						
							| 
									
										
										
										
											2019-07-25 16:03:58 +00:00
										 |  |  |                         postFilename= \ | 
					
						
							|  |  |  |                             self.server.baseDir+'/accounts/'+nickname+'@'+self.server.domain+'/outbox/'+ \ | 
					
						
							|  |  |  |                             self.server.httpPrefix+':##'+self.server.domainFull+'#users#'+nickname+'#statuses#'+statusNumber+'.json' | 
					
						
							|  |  |  |                         if os.path.isfile(postFilename): | 
					
						
							|  |  |  |                             postJsonObject={} | 
					
						
							|  |  |  |                             with open(postFilename, 'r') as fp: | 
					
						
							|  |  |  |                                 postJsonObject=commentjson.load(fp) | 
					
						
							|  |  |  |                                 # Only authorized viewers get to see likes on posts | 
					
						
							|  |  |  |                                 # Otherwize marketers could gain more social graph info | 
					
						
							|  |  |  |                                 if not authorized: | 
					
						
							|  |  |  |                                     if postJsonObject.get('likes'): | 
					
						
							|  |  |  |                                         postJsonObject['likes']={} | 
					
						
							| 
									
										
										
										
											2019-08-24 11:23:12 +00:00
										 |  |  |                                 if self._requestHTTP(): | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                                     msg= \ | 
					
						
							|  |  |  |                                         htmlIndividualPost(self.server.session, \ | 
					
						
							|  |  |  |                                                            self.server.cachedWebfingers,self.server.personCache, \ | 
					
						
							|  |  |  |                                                            nickname,self.server.domain,self.server.port, \ | 
					
						
							|  |  |  |                                                            authorized,postJsonObject, \ | 
					
						
							|  |  |  |                                                            self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                                            self.server.projectVersion).encode('utf-8') | 
					
						
							|  |  |  |                                     self._set_headers('text/html',len(msg),cookie)                     | 
					
						
							|  |  |  |                                     self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-07-25 16:03:58 +00:00
										 |  |  |                                 else: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                                     msg=json.dumps(postJsonObject).encode('utf-8') | 
					
						
							|  |  |  |                                     self._set_headers('application/json',len(msg),None) | 
					
						
							|  |  |  |                                     self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-07-25 16:03:58 +00:00
										 |  |  |                             self.server.GETbusy=False | 
					
						
							|  |  |  |                             return | 
					
						
							|  |  |  |                         else: | 
					
						
							|  |  |  |                             self._404() | 
					
						
							|  |  |  |                             self.server.GETbusy=False | 
					
						
							|  |  |  |                             return | 
					
						
							| 
									
										
										
										
											2019-07-13 19:28:14 +00:00
										 |  |  |         # get replies to a post /users/nickname/statuses/number/replies | 
					
						
							| 
									
										
										
										
											2019-07-13 20:23:42 +00:00
										 |  |  |         if self.path.endswith('/replies') or '/replies?page=' in self.path: | 
					
						
							| 
									
										
										
										
											2019-07-13 19:28:14 +00:00
										 |  |  |             if '/statuses/' in self.path and '/users/' in self.path: | 
					
						
							|  |  |  |                 namedStatus=self.path.split('/users/')[1] | 
					
						
							|  |  |  |                 if '/' in namedStatus: | 
					
						
							|  |  |  |                     postSections=namedStatus.split('/') | 
					
						
							|  |  |  |                     if len(postSections)>=4: | 
					
						
							|  |  |  |                         if postSections[3].startswith('replies'): | 
					
						
							|  |  |  |                             nickname=postSections[0] | 
					
						
							|  |  |  |                             statusNumber=postSections[2] | 
					
						
							|  |  |  |                             if len(statusNumber)>10 and statusNumber.isdigit(): | 
					
						
							|  |  |  |                                 #get the replies file | 
					
						
							| 
									
										
										
										
											2019-07-13 19:34:03 +00:00
										 |  |  |                                 boxname='outbox' | 
					
						
							|  |  |  |                                 postDir=self.server.baseDir+'/accounts/'+nickname+'@'+self.server.domain+'/'+boxname | 
					
						
							|  |  |  |                                 postRepliesFilename= \ | 
					
						
							|  |  |  |                                     postDir+'/'+ \ | 
					
						
							| 
									
										
										
										
											2019-07-25 16:03:58 +00:00
										 |  |  |                                     self.server.httpPrefix+':##'+self.server.domainFull+'#users#'+nickname+'#statuses#'+statusNumber+'.replies' | 
					
						
							| 
									
										
										
										
											2019-07-13 19:34:03 +00:00
										 |  |  |                                 if not os.path.isfile(postRepliesFilename): | 
					
						
							|  |  |  |                                     # There are no replies, so show empty collection | 
					
						
							|  |  |  |                                     repliesJson = { | 
					
						
							|  |  |  |                                         '@context': 'https://www.w3.org/ns/activitystreams', | 
					
						
							| 
									
										
										
										
											2019-07-25 16:03:58 +00:00
										 |  |  |                                         'first': self.server.httpPrefix+'://'+self.server.domainFull+'/users/'+nickname+'/statuses/'+statusNumber+'/replies?page=true', | 
					
						
							|  |  |  |                                         'id': self.server.httpPrefix+'://'+self.server.domainFull+'/users/'+nickname+'/statuses/'+statusNumber+'/replies', | 
					
						
							|  |  |  |                                         'last': self.server.httpPrefix+'://'+self.server.domainFull+'/users/'+nickname+'/statuses/'+statusNumber+'/replies?page=true', | 
					
						
							| 
									
										
										
										
											2019-07-13 19:34:03 +00:00
										 |  |  |                                         'totalItems': 0, | 
					
						
							|  |  |  |                                         'type': 'OrderedCollection'} | 
					
						
							| 
									
										
										
										
											2019-08-24 11:23:12 +00:00
										 |  |  |                                     if self._requestHTTP(): | 
					
						
							| 
									
										
										
										
											2019-08-02 16:49:42 +00:00
										 |  |  |                                         if not self.server.session: | 
					
						
							|  |  |  |                                             if self.server.debug: | 
					
						
							|  |  |  |                                                 print('DEBUG: creating new session') | 
					
						
							|  |  |  |                                             self.server.session= \ | 
					
						
							|  |  |  |                                                 createSession(self.server.domain,self.server.port,self.server.useTor) | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                                         msg=htmlPostReplies(self.server.baseDir, \ | 
					
						
							|  |  |  |                                                             self.server.session, \ | 
					
						
							|  |  |  |                                                             self.server.cachedWebfingers, \ | 
					
						
							|  |  |  |                                                             self.server.personCache, \ | 
					
						
							|  |  |  |                                                             nickname, \ | 
					
						
							|  |  |  |                                                             self.server.domain, \ | 
					
						
							|  |  |  |                                                             self.server.port, \ | 
					
						
							|  |  |  |                                                             repliesJson, \ | 
					
						
							|  |  |  |                                                             self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                                             self.server.projectVersion).encode('utf-8') | 
					
						
							|  |  |  |                                         self._set_headers('text/html',len(msg),cookie) | 
					
						
							| 
									
										
										
										
											2019-08-02 18:04:31 +00:00
										 |  |  |                                         print('----------------------------------------------------') | 
					
						
							|  |  |  |                                         pprint(repliesJson) | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                                         self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-07-20 21:13:36 +00:00
										 |  |  |                                     else: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                                         msg=json.dumps(repliesJson).encode('utf-8') | 
					
						
							|  |  |  |                                         self._set_headers('application/json',len(msg),None) | 
					
						
							|  |  |  |                                         self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-07-13 19:34:03 +00:00
										 |  |  |                                     self.server.GETbusy=False | 
					
						
							|  |  |  |                                     return | 
					
						
							|  |  |  |                                 else: | 
					
						
							|  |  |  |                                     # replies exist. Itterate through the text file containing message ids | 
					
						
							|  |  |  |                                     repliesJson = { | 
					
						
							|  |  |  |                                         '@context': 'https://www.w3.org/ns/activitystreams', | 
					
						
							| 
									
										
										
										
											2019-07-25 16:03:58 +00:00
										 |  |  |                                         'id': self.server.httpPrefix+'://'+self.server.domainFull+'/users/'+nickname+'/statuses/'+statusNumber+'?page=true', | 
					
						
							| 
									
										
										
										
											2019-07-13 19:34:03 +00:00
										 |  |  |                                         'orderedItems': [ | 
					
						
							|  |  |  |                                         ], | 
					
						
							| 
									
										
										
										
											2019-07-25 16:03:58 +00:00
										 |  |  |                                         'partOf': self.server.httpPrefix+'://'+self.server.domainFull+'/users/'+nickname+'/statuses/'+statusNumber, | 
					
						
							| 
									
										
										
										
											2019-07-13 19:34:03 +00:00
										 |  |  |                                         'type': 'OrderedCollectionPage'} | 
					
						
							| 
									
										
										
										
											2019-07-25 11:18:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-13 19:34:03 +00:00
										 |  |  |                                     # populate the items list with replies | 
					
						
							| 
									
										
										
										
											2019-08-02 18:37:23 +00:00
										 |  |  |                                     populateRepliesJson(self.server.baseDir, \ | 
					
						
							|  |  |  |                                                         nickname, \ | 
					
						
							|  |  |  |                                                         self.server.domain, \ | 
					
						
							|  |  |  |                                                         postRepliesFilename, \ | 
					
						
							|  |  |  |                                                         authorized, \ | 
					
						
							|  |  |  |                                                         repliesJson) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-13 19:34:03 +00:00
										 |  |  |                                     # send the replies json | 
					
						
							| 
									
										
										
										
											2019-08-24 11:23:12 +00:00
										 |  |  |                                     if self._requestHTTP(): | 
					
						
							| 
									
										
										
										
											2019-08-02 16:49:42 +00:00
										 |  |  |                                         if not self.server.session: | 
					
						
							|  |  |  |                                             if self.server.debug: | 
					
						
							|  |  |  |                                                 print('DEBUG: creating new session') | 
					
						
							|  |  |  |                                             self.server.session= \ | 
					
						
							|  |  |  |                                                 createSession(self.server.domain,self.server.port,self.server.useTor) | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                                         msg=htmlPostReplies(self.server.baseDir, \ | 
					
						
							|  |  |  |                                                             self.server.session, \ | 
					
						
							|  |  |  |                                                             self.server.cachedWebfingers, \ | 
					
						
							|  |  |  |                                                             self.server.personCache, \ | 
					
						
							|  |  |  |                                                             nickname, \ | 
					
						
							|  |  |  |                                                             self.server.domain, \ | 
					
						
							|  |  |  |                                                             self.server.port, \ | 
					
						
							|  |  |  |                                                             repliesJson, \ | 
					
						
							|  |  |  |                                                             self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                                             self.server.projectVersion).encode('utf-8') | 
					
						
							|  |  |  |                                         self._set_headers('text/html',len(msg),cookie) | 
					
						
							|  |  |  |                                         self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-07-20 21:13:36 +00:00
										 |  |  |                                     else: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                                         msg=json.dumps(repliesJson).encode('utf-8') | 
					
						
							|  |  |  |                                         self._set_headers('application/json',len(msg),None) | 
					
						
							|  |  |  |                                         self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-07-13 19:34:03 +00:00
										 |  |  |                                     self.server.GETbusy=False | 
					
						
							|  |  |  |                                     return | 
					
						
							| 
									
										
										
										
											2019-07-13 19:28:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-22 17:21:45 +00:00
										 |  |  |         if self.path.endswith('/roles') and '/users/' in self.path: | 
					
						
							|  |  |  |             namedStatus=self.path.split('/users/')[1] | 
					
						
							|  |  |  |             if '/' in namedStatus: | 
					
						
							|  |  |  |                 postSections=namedStatus.split('/') | 
					
						
							|  |  |  |                 nickname=postSections[0] | 
					
						
							|  |  |  |                 actorFilename=self.server.baseDir+'/accounts/'+nickname+'@'+self.server.domain+'.json' | 
					
						
							|  |  |  |                 if os.path.isfile(actorFilename): | 
					
						
							|  |  |  |                     with open(actorFilename, 'r') as fp: | 
					
						
							|  |  |  |                         actorJson=commentjson.load(fp) | 
					
						
							|  |  |  |                         if actorJson.get('roles'): | 
					
						
							| 
									
										
										
										
											2019-08-24 11:23:12 +00:00
										 |  |  |                             if self._requestHTTP(): | 
					
						
							| 
									
										
										
										
											2019-07-22 17:21:45 +00:00
										 |  |  |                                 getPerson = \ | 
					
						
							|  |  |  |                                     personLookup(self.server.domain,self.path.replace('/roles',''), \ | 
					
						
							|  |  |  |                                                  self.server.baseDir) | 
					
						
							| 
									
										
										
										
											2019-07-22 20:01:46 +00:00
										 |  |  |                                 if getPerson: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                                     msg=htmlProfile(self.server.projectVersion, \ | 
					
						
							|  |  |  |                                                     self.server.baseDir, \ | 
					
						
							|  |  |  |                                                     self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                                     True, \ | 
					
						
							|  |  |  |                                                     self.server.ocapAlways, \ | 
					
						
							|  |  |  |                                                     getPerson,'roles', \ | 
					
						
							|  |  |  |                                                     self.server.session, \ | 
					
						
							|  |  |  |                                                     self.server.cachedWebfingers, \ | 
					
						
							|  |  |  |                                                     self.server.personCache, \ | 
					
						
							|  |  |  |                                                     actorJson['roles']).encode('utf-8') | 
					
						
							|  |  |  |                                     self._set_headers('text/html',len(msg),cookie) | 
					
						
							|  |  |  |                                     self.wfile.write(msg)      | 
					
						
							| 
									
										
										
										
											2019-07-22 17:21:45 +00:00
										 |  |  |                             else: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                                 msg=json.dumps(actorJson['roles']).encode('utf-8') | 
					
						
							|  |  |  |                                 self._set_headers('application/json',len(msg),None) | 
					
						
							|  |  |  |                                 self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-07-22 20:01:46 +00:00
										 |  |  |                             self.server.GETbusy=False | 
					
						
							| 
									
										
										
										
											2019-07-22 17:21:45 +00:00
										 |  |  |                             return | 
					
						
							| 
									
										
										
										
											2019-07-22 20:01:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-27 17:33:11 +00:00
										 |  |  |         # show skills on the profile page | 
					
						
							| 
									
										
										
										
											2019-07-22 20:01:46 +00:00
										 |  |  |         if self.path.endswith('/skills') and '/users/' in self.path: | 
					
						
							|  |  |  |             namedStatus=self.path.split('/users/')[1] | 
					
						
							|  |  |  |             if '/' in namedStatus: | 
					
						
							|  |  |  |                 postSections=namedStatus.split('/') | 
					
						
							|  |  |  |                 nickname=postSections[0] | 
					
						
							|  |  |  |                 actorFilename=self.server.baseDir+'/accounts/'+nickname+'@'+self.server.domain+'.json' | 
					
						
							|  |  |  |                 if os.path.isfile(actorFilename): | 
					
						
							|  |  |  |                     with open(actorFilename, 'r') as fp: | 
					
						
							|  |  |  |                         actorJson=commentjson.load(fp) | 
					
						
							|  |  |  |                         if actorJson.get('skills'): | 
					
						
							| 
									
										
										
										
											2019-08-24 11:23:12 +00:00
										 |  |  |                             if self._requestHTTP(): | 
					
						
							| 
									
										
										
										
											2019-07-22 20:01:46 +00:00
										 |  |  |                                 getPerson = \ | 
					
						
							|  |  |  |                                     personLookup(self.server.domain,self.path.replace('/skills',''), \ | 
					
						
							|  |  |  |                                                  self.server.baseDir) | 
					
						
							|  |  |  |                                 if getPerson: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                                     msg=htmlProfile(self.server.projectVersion, \ | 
					
						
							|  |  |  |                                                     self.server.baseDir, \ | 
					
						
							|  |  |  |                                                     self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                                     True, \ | 
					
						
							|  |  |  |                                                     self.server.ocapAlways, \ | 
					
						
							|  |  |  |                                                     getPerson,'skills', \ | 
					
						
							|  |  |  |                                                     self.server.session, \ | 
					
						
							|  |  |  |                                                     self.server.cachedWebfingers, \ | 
					
						
							|  |  |  |                                                     self.server.personCache, \ | 
					
						
							|  |  |  |                                                     actorJson['skills']).encode('utf-8') | 
					
						
							|  |  |  |                                     self._set_headers('text/html',len(msg),cookie) | 
					
						
							|  |  |  |                                     self.wfile.write(msg)      | 
					
						
							| 
									
										
										
										
											2019-07-22 20:01:46 +00:00
										 |  |  |                             else: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                                 msg=json.dumps(actorJson['skills']).encode('utf-8') | 
					
						
							|  |  |  |                                 self._set_headers('application/json',len(msg),None) | 
					
						
							|  |  |  |                                 self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-07-22 20:01:46 +00:00
										 |  |  |                             self.server.GETbusy=False | 
					
						
							|  |  |  |                             return | 
					
						
							| 
									
										
										
										
											2019-08-27 17:35:12 +00:00
										 |  |  |             actor=self.path.replace('/skills','') | 
					
						
							| 
									
										
										
										
											2019-08-27 17:33:11 +00:00
										 |  |  |             self._redirect_headers(actor,cookie) | 
					
						
							|  |  |  |             self.server.GETbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-07-22 20:01:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-06 21:33:46 +00:00
										 |  |  |         # get an individual post from the path /users/nickname/statuses/number | 
					
						
							| 
									
										
										
										
											2019-07-06 21:24:47 +00:00
										 |  |  |         if '/statuses/' in self.path and '/users/' in self.path: | 
					
						
							|  |  |  |             namedStatus=self.path.split('/users/')[1] | 
					
						
							|  |  |  |             if '/' in namedStatus: | 
					
						
							|  |  |  |                 postSections=namedStatus.split('/') | 
					
						
							| 
									
										
										
										
											2019-07-13 19:28:14 +00:00
										 |  |  |                 if len(postSections)>=3: | 
					
						
							| 
									
										
										
										
											2019-07-06 21:24:47 +00:00
										 |  |  |                     nickname=postSections[0] | 
					
						
							|  |  |  |                     statusNumber=postSections[2] | 
					
						
							| 
									
										
										
										
											2019-07-06 21:33:46 +00:00
										 |  |  |                     if len(statusNumber)>10 and statusNumber.isdigit(): | 
					
						
							| 
									
										
										
										
											2019-07-22 17:21:45 +00:00
										 |  |  |                         postFilename= \ | 
					
						
							|  |  |  |                             self.server.baseDir+'/accounts/'+nickname+'@'+self.server.domain+'/outbox/'+ \ | 
					
						
							| 
									
										
										
										
											2019-07-25 16:03:58 +00:00
										 |  |  |                             self.server.httpPrefix+':##'+self.server.domainFull+'#users#'+nickname+'#statuses#'+statusNumber+'.json' | 
					
						
							| 
									
										
										
										
											2019-07-22 17:21:45 +00:00
										 |  |  |                         if os.path.isfile(postFilename): | 
					
						
							|  |  |  |                             postJsonObject={} | 
					
						
							|  |  |  |                             with open(postFilename, 'r') as fp: | 
					
						
							|  |  |  |                                 postJsonObject=commentjson.load(fp) | 
					
						
							|  |  |  |                                 # Only authorized viewers get to see likes on posts | 
					
						
							|  |  |  |                                 # Otherwize marketers could gain more social graph info | 
					
						
							| 
									
										
										
										
											2019-07-25 11:18:35 +00:00
										 |  |  |                                 if not authorized: | 
					
						
							| 
									
										
										
										
											2019-07-22 17:21:45 +00:00
										 |  |  |                                     if postJsonObject.get('likes'): | 
					
						
							|  |  |  |                                         postJsonObject['likes']={}                                     | 
					
						
							| 
									
										
										
										
											2019-08-24 11:23:12 +00:00
										 |  |  |                                 if self._requestHTTP(): | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                                     msg=htmlIndividualPost(self.server.baseDir, \ | 
					
						
							|  |  |  |                                                            self.server.session, \ | 
					
						
							|  |  |  |                                                            self.server.cachedWebfingers,self.server.personCache, \ | 
					
						
							|  |  |  |                                                            nickname,self.server.domain,self.server.port, \ | 
					
						
							|  |  |  |                                                            authorized,postJsonObject, \ | 
					
						
							|  |  |  |                                                            self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                                            self.server.projectVersion).encode('utf-8') | 
					
						
							|  |  |  |                                     self._set_headers('text/html',len(msg),cookie) | 
					
						
							|  |  |  |                                     self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-07-22 17:21:45 +00:00
										 |  |  |                                 else: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                                     msg=json.dumps(postJsonObject).encode('utf-8') | 
					
						
							|  |  |  |                                     self._set_headers('application/json',len(msg),None) | 
					
						
							|  |  |  |                                     self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-07-22 17:21:45 +00:00
										 |  |  |                             self.server.GETbusy=False | 
					
						
							|  |  |  |                             return | 
					
						
							|  |  |  |                         else: | 
					
						
							|  |  |  |                             self._404() | 
					
						
							|  |  |  |                             self.server.GETbusy=False | 
					
						
							|  |  |  |                             return | 
					
						
							| 
									
										
										
										
											2019-08-12 13:22:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-03 19:32:07 +00:00
										 |  |  |         # get the inbox for a given person | 
					
						
							| 
									
										
										
										
											2019-08-12 13:22:17 +00:00
										 |  |  |         if self.path.endswith('/inbox') or '/inbox?page=' in self.path: | 
					
						
							| 
									
										
										
										
											2019-07-03 19:32:07 +00:00
										 |  |  |             if '/users/' in self.path: | 
					
						
							| 
									
										
										
										
											2019-07-25 11:18:35 +00:00
										 |  |  |                 if authorized: | 
					
						
							| 
									
										
										
										
											2019-07-12 11:05:43 +00:00
										 |  |  |                     inboxFeed=personBoxJson(self.server.baseDir, \ | 
					
						
							|  |  |  |                                             self.server.domain, \ | 
					
						
							|  |  |  |                                             self.server.port, \ | 
					
						
							|  |  |  |                                             self.path, \ | 
					
						
							|  |  |  |                                             self.server.httpPrefix, \ | 
					
						
							| 
									
										
										
										
											2019-07-14 11:15:28 +00:00
										 |  |  |                                             maxPostsInFeed, 'inbox', \ | 
					
						
							|  |  |  |                                             True,self.server.ocapAlways) | 
					
						
							| 
									
										
										
										
											2019-07-12 11:05:43 +00:00
										 |  |  |                     if inboxFeed: | 
					
						
							| 
									
										
										
										
											2019-08-24 11:23:12 +00:00
										 |  |  |                         if self._requestHTTP(): | 
					
						
							| 
									
										
										
										
											2019-07-24 12:02:28 +00:00
										 |  |  |                             nickname=self.path.replace('/users/','').replace('/inbox','') | 
					
						
							| 
									
										
										
										
											2019-07-31 20:37:19 +00:00
										 |  |  |                             pageNumber=1 | 
					
						
							| 
									
										
										
										
											2019-07-24 12:02:28 +00:00
										 |  |  |                             if '?page=' in nickname: | 
					
						
							| 
									
										
										
										
											2019-07-31 20:37:19 +00:00
										 |  |  |                                 pageNumber=nickname.split('?page=')[1] | 
					
						
							| 
									
										
										
										
											2019-07-24 12:02:28 +00:00
										 |  |  |                                 nickname=nickname.split('?page=')[0] | 
					
						
							| 
									
										
										
										
											2019-07-31 20:37:19 +00:00
										 |  |  |                                 if pageNumber.isdigit(): | 
					
						
							|  |  |  |                                     pageNumber=int(pageNumber) | 
					
						
							|  |  |  |                                 else: | 
					
						
							|  |  |  |                                     pageNumber=1                                 | 
					
						
							| 
									
										
										
										
											2019-07-24 11:03:56 +00:00
										 |  |  |                             if 'page=' not in self.path: | 
					
						
							|  |  |  |                                 # if no page was specified then show the first | 
					
						
							|  |  |  |                                 inboxFeed=personBoxJson(self.server.baseDir, \ | 
					
						
							|  |  |  |                                                         self.server.domain, \ | 
					
						
							|  |  |  |                                                         self.server.port, \ | 
					
						
							|  |  |  |                                                         self.path+'?page=1', \ | 
					
						
							|  |  |  |                                                         self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                                         maxPostsInFeed, 'inbox', \ | 
					
						
							| 
									
										
										
										
											2019-07-24 12:02:28 +00:00
										 |  |  |                                                         True,self.server.ocapAlways) | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                             msg=htmlInbox(pageNumber,maxPostsInFeed, \ | 
					
						
							|  |  |  |                                           self.server.session, \ | 
					
						
							|  |  |  |                                           self.server.baseDir, \ | 
					
						
							|  |  |  |                                           self.server.cachedWebfingers, \ | 
					
						
							|  |  |  |                                           self.server.personCache, \ | 
					
						
							|  |  |  |                                           nickname, \ | 
					
						
							|  |  |  |                                           self.server.domain, \ | 
					
						
							|  |  |  |                                           self.server.port, \ | 
					
						
							|  |  |  |                                           inboxFeed, \ | 
					
						
							|  |  |  |                                           self.server.allowDeletion, \ | 
					
						
							|  |  |  |                                           self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                           self.server.projectVersion).encode('utf-8') | 
					
						
							|  |  |  |                             self._set_headers('text/html',len(msg),cookie) | 
					
						
							|  |  |  |                             self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-07-20 21:13:36 +00:00
										 |  |  |                         else: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                             msg=json.dumps(inboxFeed).encode('utf-8') | 
					
						
							|  |  |  |                             self._set_headers('application/json',len(msg),None) | 
					
						
							|  |  |  |                             self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-07-12 11:05:43 +00:00
										 |  |  |                         self.server.GETbusy=False | 
					
						
							|  |  |  |                         return | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     if self.server.debug: | 
					
						
							| 
									
										
										
										
											2019-08-04 21:25:19 +00:00
										 |  |  |                         nickname=self.path.replace('/users/','').replace('/inbox','') | 
					
						
							| 
									
										
										
										
											2019-07-12 11:05:43 +00:00
										 |  |  |                         print('DEBUG: '+nickname+ \ | 
					
						
							|  |  |  |                               ' was not authorized to access '+self.path) | 
					
						
							| 
									
										
										
										
											2019-08-05 16:05:08 +00:00
										 |  |  |             if self.path!='/inbox': | 
					
						
							|  |  |  |                 # not the shared inbox | 
					
						
							|  |  |  |                 if self.server.debug: | 
					
						
							|  |  |  |                     print('DEBUG: GET access to inbox is unauthorized') | 
					
						
							|  |  |  |                 self.send_response(405) | 
					
						
							|  |  |  |                 self.end_headers() | 
					
						
							| 
									
										
										
										
											2019-08-12 13:22:17 +00:00
										 |  |  |                 self.server.GETbusy=False | 
					
						
							| 
									
										
										
										
											2019-08-05 16:05:08 +00:00
										 |  |  |                 return | 
					
						
							| 
									
										
										
										
											2019-08-25 16:09:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # get the inbox for a given person | 
					
						
							|  |  |  |         if self.path.endswith('/dm') or '/dm?page=' in self.path: | 
					
						
							|  |  |  |             if '/users/' in self.path: | 
					
						
							|  |  |  |                 if authorized: | 
					
						
							|  |  |  |                     inboxDMFeed=personBoxJson(self.server.baseDir, \ | 
					
						
							| 
									
										
										
										
											2019-08-25 17:34:09 +00:00
										 |  |  |                                               self.server.domain, \ | 
					
						
							|  |  |  |                                               self.server.port, \ | 
					
						
							|  |  |  |                                               self.path, \ | 
					
						
							|  |  |  |                                               self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                               maxPostsInFeed, 'dm', \ | 
					
						
							|  |  |  |                                               True,self.server.ocapAlways) | 
					
						
							| 
									
										
										
										
											2019-08-25 16:09:56 +00:00
										 |  |  |                     if inboxDMFeed: | 
					
						
							|  |  |  |                         if self._requestHTTP(): | 
					
						
							|  |  |  |                             nickname=self.path.replace('/users/','').replace('/dm','') | 
					
						
							|  |  |  |                             pageNumber=1 | 
					
						
							|  |  |  |                             if '?page=' in nickname: | 
					
						
							|  |  |  |                                 pageNumber=nickname.split('?page=')[1] | 
					
						
							|  |  |  |                                 nickname=nickname.split('?page=')[0] | 
					
						
							|  |  |  |                                 if pageNumber.isdigit(): | 
					
						
							|  |  |  |                                     pageNumber=int(pageNumber) | 
					
						
							|  |  |  |                                 else: | 
					
						
							|  |  |  |                                     pageNumber=1                                 | 
					
						
							|  |  |  |                             if 'page=' not in self.path: | 
					
						
							|  |  |  |                                 # if no page was specified then show the first | 
					
						
							|  |  |  |                                 inboxDMFeed=personBoxJson(self.server.baseDir, \ | 
					
						
							|  |  |  |                                                         self.server.domain, \ | 
					
						
							|  |  |  |                                                         self.server.port, \ | 
					
						
							|  |  |  |                                                         self.path+'?page=1', \ | 
					
						
							|  |  |  |                                                         self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                                         maxPostsInFeed, 'dm', \ | 
					
						
							|  |  |  |                                                         True,self.server.ocapAlways) | 
					
						
							| 
									
										
										
										
											2019-08-25 17:34:09 +00:00
										 |  |  |                             msg=htmlInboxDMs(pageNumber,maxPostsInFeed, \ | 
					
						
							|  |  |  |                                              self.server.session, \ | 
					
						
							|  |  |  |                                              self.server.baseDir, \ | 
					
						
							|  |  |  |                                              self.server.cachedWebfingers, \ | 
					
						
							|  |  |  |                                              self.server.personCache, \ | 
					
						
							|  |  |  |                                              nickname, \ | 
					
						
							|  |  |  |                                              self.server.domain, \ | 
					
						
							|  |  |  |                                              self.server.port, \ | 
					
						
							|  |  |  |                                              inboxDMFeed, \ | 
					
						
							|  |  |  |                                              self.server.allowDeletion, \ | 
					
						
							|  |  |  |                                              self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                              self.server.projectVersion).encode('utf-8') | 
					
						
							| 
									
										
										
										
											2019-08-25 16:09:56 +00:00
										 |  |  |                             self._set_headers('text/html',len(msg),cookie) | 
					
						
							|  |  |  |                             self.wfile.write(msg) | 
					
						
							|  |  |  |                         else: | 
					
						
							|  |  |  |                             msg=json.dumps(inboxDMFeed).encode('utf-8') | 
					
						
							|  |  |  |                             self._set_headers('application/json',len(msg),None) | 
					
						
							|  |  |  |                             self.wfile.write(msg) | 
					
						
							|  |  |  |                         self.server.GETbusy=False | 
					
						
							|  |  |  |                         return | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     if self.server.debug: | 
					
						
							|  |  |  |                         nickname=self.path.replace('/users/','').replace('/dm','') | 
					
						
							|  |  |  |                         print('DEBUG: '+nickname+ \ | 
					
						
							|  |  |  |                               ' was not authorized to access '+self.path) | 
					
						
							|  |  |  |             if self.path!='/dm': | 
					
						
							|  |  |  |                 # not the DM inbox | 
					
						
							|  |  |  |                 if self.server.debug: | 
					
						
							|  |  |  |                     print('DEBUG: GET access to inbox is unauthorized') | 
					
						
							|  |  |  |                 self.send_response(405) | 
					
						
							|  |  |  |                 self.end_headers() | 
					
						
							|  |  |  |                 self.server.GETbusy=False | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-29 14:35:26 +00:00
										 |  |  |         # get outbox feed for a person | 
					
						
							| 
									
										
										
										
											2019-07-04 16:24:23 +00:00
										 |  |  |         outboxFeed=personBoxJson(self.server.baseDir,self.server.domain, \ | 
					
						
							|  |  |  |                                  self.server.port,self.path, \ | 
					
						
							|  |  |  |                                  self.server.httpPrefix, \ | 
					
						
							| 
									
										
										
										
											2019-07-12 11:20:59 +00:00
										 |  |  |                                  maxPostsInFeed, 'outbox', \ | 
					
						
							| 
									
										
										
										
											2019-07-25 11:18:35 +00:00
										 |  |  |                                  authorized, \ | 
					
						
							| 
									
										
										
										
											2019-07-14 11:15:28 +00:00
										 |  |  |                                  self.server.ocapAlways) | 
					
						
							| 
									
										
										
										
											2019-06-29 14:41:23 +00:00
										 |  |  |         if outboxFeed: | 
					
						
							| 
									
										
										
										
											2019-08-24 11:23:12 +00:00
										 |  |  |             if self._requestHTTP(): | 
					
						
							| 
									
										
										
										
											2019-07-24 12:02:28 +00:00
										 |  |  |                 nickname=self.path.replace('/users/','').replace('/outbox','') | 
					
						
							| 
									
										
										
										
											2019-07-31 20:37:19 +00:00
										 |  |  |                 pageNumber=1 | 
					
						
							| 
									
										
										
										
											2019-07-24 12:02:28 +00:00
										 |  |  |                 if '?page=' in nickname: | 
					
						
							| 
									
										
										
										
											2019-07-31 20:37:19 +00:00
										 |  |  |                     pageNumber=nickname.split('?page=')[1] | 
					
						
							| 
									
										
										
										
											2019-07-24 12:02:28 +00:00
										 |  |  |                     nickname=nickname.split('?page=')[0] | 
					
						
							| 
									
										
										
										
											2019-07-31 20:37:19 +00:00
										 |  |  |                     if pageNumber.isdigit(): | 
					
						
							|  |  |  |                         pageNumber=int(pageNumber) | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         pageNumber=1 | 
					
						
							| 
									
										
										
										
											2019-07-24 11:03:56 +00:00
										 |  |  |                 if 'page=' not in self.path: | 
					
						
							|  |  |  |                     # if a page wasn't specified then show the first one | 
					
						
							|  |  |  |                     outboxFeed=personBoxJson(self.server.baseDir,self.server.domain, \ | 
					
						
							|  |  |  |                                              self.server.port,self.path+'?page=1', \ | 
					
						
							|  |  |  |                                              self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                              maxPostsInFeed, 'outbox', \ | 
					
						
							| 
									
										
										
										
											2019-07-25 11:18:35 +00:00
										 |  |  |                                              authorized, \ | 
					
						
							| 
									
										
										
										
											2019-07-24 11:03:56 +00:00
										 |  |  |                                              self.server.ocapAlways) | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                 msg=htmlOutbox(pageNumber,maxPostsInFeed, \ | 
					
						
							|  |  |  |                                self.server.session, \ | 
					
						
							|  |  |  |                                self.server.baseDir, \ | 
					
						
							|  |  |  |                                self.server.cachedWebfingers, \ | 
					
						
							|  |  |  |                                self.server.personCache, \ | 
					
						
							|  |  |  |                                nickname, \ | 
					
						
							|  |  |  |                                self.server.domain, \ | 
					
						
							|  |  |  |                                self.server.port, \ | 
					
						
							|  |  |  |                                outboxFeed, \ | 
					
						
							|  |  |  |                                self.server.allowDeletion, \ | 
					
						
							|  |  |  |                                self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                self.server.projectVersion).encode('utf-8') | 
					
						
							|  |  |  |                 self._set_headers('text/html',len(msg),cookie) | 
					
						
							|  |  |  |                 self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-07-20 21:13:36 +00:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                 msg=json.dumps(outboxFeed).encode('utf-8') | 
					
						
							|  |  |  |                 self._set_headers('application/json',len(msg),None) | 
					
						
							|  |  |  |                 self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-07-01 14:30:48 +00:00
										 |  |  |             self.server.GETbusy=False | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-07-23 12:33:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-12 13:22:17 +00:00
										 |  |  |         # get the moderation feed for a moderator | 
					
						
							|  |  |  |         if self.path.endswith('/moderation') or '/moderation?page=' in self.path: | 
					
						
							|  |  |  |             if '/users/' in self.path: | 
					
						
							|  |  |  |                 if authorized: | 
					
						
							|  |  |  |                     moderationFeed= \ | 
					
						
							|  |  |  |                         personBoxJson(self.server.baseDir, \ | 
					
						
							|  |  |  |                                       self.server.domain, \ | 
					
						
							|  |  |  |                                       self.server.port, \ | 
					
						
							|  |  |  |                                       self.path, \ | 
					
						
							|  |  |  |                                       self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                       maxPostsInFeed, 'moderation', \ | 
					
						
							|  |  |  |                                       True,self.server.ocapAlways) | 
					
						
							|  |  |  |                     if moderationFeed: | 
					
						
							| 
									
										
										
										
											2019-08-24 11:23:12 +00:00
										 |  |  |                         if self._requestHTTP(): | 
					
						
							| 
									
										
										
										
											2019-08-12 13:22:17 +00:00
										 |  |  |                             nickname=self.path.replace('/users/','').replace('/moderation','') | 
					
						
							|  |  |  |                             pageNumber=1 | 
					
						
							|  |  |  |                             if '?page=' in nickname: | 
					
						
							|  |  |  |                                 pageNumber=nickname.split('?page=')[1] | 
					
						
							|  |  |  |                                 nickname=nickname.split('?page=')[0] | 
					
						
							|  |  |  |                                 if pageNumber.isdigit(): | 
					
						
							|  |  |  |                                     pageNumber=int(pageNumber) | 
					
						
							|  |  |  |                                 else: | 
					
						
							|  |  |  |                                     pageNumber=1                                 | 
					
						
							|  |  |  |                             if 'page=' not in self.path: | 
					
						
							|  |  |  |                                 # if no page was specified then show the first | 
					
						
							|  |  |  |                                 moderationFeed= \ | 
					
						
							|  |  |  |                                     personBoxJson(self.server.baseDir, \ | 
					
						
							|  |  |  |                                                   self.server.domain, \ | 
					
						
							|  |  |  |                                                   self.server.port, \ | 
					
						
							|  |  |  |                                                   self.path+'?page=1', \ | 
					
						
							|  |  |  |                                                   self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                                   maxPostsInFeed, 'moderation', \ | 
					
						
							|  |  |  |                                                   True,self.server.ocapAlways) | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                             msg=htmlModeration(pageNumber,maxPostsInFeed, \ | 
					
						
							|  |  |  |                                                self.server.session, \ | 
					
						
							|  |  |  |                                                self.server.baseDir, \ | 
					
						
							|  |  |  |                                                self.server.cachedWebfingers, \ | 
					
						
							|  |  |  |                                                self.server.personCache, \ | 
					
						
							|  |  |  |                                                nickname, \ | 
					
						
							|  |  |  |                                                self.server.domain, \ | 
					
						
							|  |  |  |                                                self.server.port, \ | 
					
						
							|  |  |  |                                                moderationFeed, \ | 
					
						
							|  |  |  |                                                True, \ | 
					
						
							|  |  |  |                                                self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                                self.server.projectVersion).encode('utf-8') | 
					
						
							|  |  |  |                             self._set_headers('text/html',len(msg),cookie) | 
					
						
							|  |  |  |                             self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-08-12 13:22:17 +00:00
										 |  |  |                         else: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                             msg=json.dumps(moderationFeed).encode('utf-8') | 
					
						
							|  |  |  |                             self._set_headers('application/json',len(msg),None) | 
					
						
							|  |  |  |                             self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-08-12 13:22:17 +00:00
										 |  |  |                         self.server.GETbusy=False | 
					
						
							|  |  |  |                         return | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     if self.server.debug: | 
					
						
							|  |  |  |                         nickname=self.path.replace('/users/','').replace('/moderation','') | 
					
						
							|  |  |  |                         print('DEBUG: '+nickname+ \ | 
					
						
							|  |  |  |                               ' was not authorized to access '+self.path) | 
					
						
							|  |  |  |             if self.server.debug: | 
					
						
							|  |  |  |                 print('DEBUG: GET access to moderation feed is unauthorized') | 
					
						
							|  |  |  |             self.send_response(405) | 
					
						
							|  |  |  |             self.end_headers() | 
					
						
							|  |  |  |             self.server.GETbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2019-07-24 09:53:07 +00:00
										 |  |  |         shares=getSharesFeedForPerson(self.server.baseDir, \ | 
					
						
							|  |  |  |                                       self.server.domain, \ | 
					
						
							| 
									
										
										
										
											2019-07-23 12:33:09 +00:00
										 |  |  |                                       self.server.port,self.path, \ | 
					
						
							|  |  |  |                                       self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                       sharesPerPage) | 
					
						
							|  |  |  |         if shares: | 
					
						
							| 
									
										
										
										
											2019-08-24 11:23:12 +00:00
										 |  |  |             if self._requestHTTP(): | 
					
						
							| 
									
										
										
										
											2019-07-23 12:33:09 +00:00
										 |  |  |                 if 'page=' not in self.path: | 
					
						
							|  |  |  |                     # get a page of shares, not the summary | 
					
						
							|  |  |  |                     shares=getSharesFeedForPerson(self.server.baseDir,self.server.domain, \ | 
					
						
							|  |  |  |                                                   self.server.port,self.path+'?page=true', \ | 
					
						
							|  |  |  |                                                   self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                                   sharesPerPage) | 
					
						
							|  |  |  |                 getPerson = personLookup(self.server.domain,self.path.replace('/shares',''), \ | 
					
						
							|  |  |  |                                          self.server.baseDir) | 
					
						
							|  |  |  |                 if getPerson: | 
					
						
							|  |  |  |                     if not self.server.session: | 
					
						
							|  |  |  |                         if self.server.debug: | 
					
						
							|  |  |  |                             print('DEBUG: creating new session') | 
					
						
							|  |  |  |                         self.server.session= \ | 
					
						
							|  |  |  |                             createSession(self.server.domain,self.server.port,self.server.useTor) | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                     msg=htmlProfile(self.server.projectVersion, \ | 
					
						
							|  |  |  |                                     self.server.baseDir, \ | 
					
						
							|  |  |  |                                     self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                     authorized, \ | 
					
						
							|  |  |  |                                     self.server.ocapAlways, \ | 
					
						
							|  |  |  |                                     getPerson,'shares', \ | 
					
						
							|  |  |  |                                     self.server.session, \ | 
					
						
							|  |  |  |                                     self.server.cachedWebfingers, \ | 
					
						
							|  |  |  |                                     self.server.personCache, \ | 
					
						
							|  |  |  |                                     shares).encode('utf-8') | 
					
						
							|  |  |  |                     self._set_headers('text/html',len(msg),cookie) | 
					
						
							|  |  |  |                     self.wfile.write(msg)                 | 
					
						
							| 
									
										
										
										
											2019-07-23 12:33:09 +00:00
										 |  |  |                     self.server.GETbusy=False | 
					
						
							|  |  |  |                     return | 
					
						
							|  |  |  |             else: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                 msg=json.dumps(shares).encode('utf-8') | 
					
						
							|  |  |  |                 self._set_headers('application/json',len(msg),None) | 
					
						
							|  |  |  |                 self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-07-23 12:33:09 +00:00
										 |  |  |                 self.server.GETbusy=False | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-02 20:54:22 +00:00
										 |  |  |         following=getFollowingFeed(self.server.baseDir,self.server.domain, \ | 
					
						
							|  |  |  |                                    self.server.port,self.path, \ | 
					
						
							| 
									
										
										
										
											2019-07-22 09:38:02 +00:00
										 |  |  |                                    self.server.httpPrefix, \ | 
					
						
							| 
									
										
										
										
											2019-07-19 08:40:51 +00:00
										 |  |  |                                    authorized,followsPerPage) | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  |         if following: | 
					
						
							| 
									
										
										
										
											2019-08-24 11:23:12 +00:00
										 |  |  |             if self._requestHTTP(): | 
					
						
							| 
									
										
										
										
											2019-07-22 09:38:02 +00:00
										 |  |  |                 if 'page=' not in self.path: | 
					
						
							|  |  |  |                     # get a page of following, not the summary | 
					
						
							|  |  |  |                     following=getFollowingFeed(self.server.baseDir,self.server.domain, \ | 
					
						
							| 
									
										
										
										
											2019-07-22 11:44:31 +00:00
										 |  |  |                                                self.server.port,self.path+'?page=true', \ | 
					
						
							| 
									
										
										
										
											2019-07-22 09:38:02 +00:00
										 |  |  |                                                self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                                authorized,followsPerPage) | 
					
						
							|  |  |  |                 getPerson = personLookup(self.server.domain,self.path.replace('/following',''), \ | 
					
						
							|  |  |  |                                          self.server.baseDir) | 
					
						
							|  |  |  |                 if getPerson: | 
					
						
							| 
									
										
										
										
											2019-07-22 14:09:21 +00:00
										 |  |  |                     if not self.server.session: | 
					
						
							|  |  |  |                         if self.server.debug: | 
					
						
							|  |  |  |                             print('DEBUG: creating new session') | 
					
						
							|  |  |  |                         self.server.session= \ | 
					
						
							|  |  |  |                             createSession(self.server.domain,self.server.port,self.server.useTor) | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |                     msg=htmlProfile(self.server.projectVersion, \ | 
					
						
							|  |  |  |                                     self.server.baseDir, \ | 
					
						
							|  |  |  |                                     self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                     authorized, \ | 
					
						
							|  |  |  |                                     self.server.ocapAlways, \ | 
					
						
							|  |  |  |                                     getPerson,'following', \ | 
					
						
							|  |  |  |                                     self.server.session, \ | 
					
						
							|  |  |  |                                     self.server.cachedWebfingers, \ | 
					
						
							|  |  |  |                                     self.server.personCache, \ | 
					
						
							|  |  |  |                                     following).encode('utf-8') | 
					
						
							|  |  |  |                     self._set_headers('text/html',len(msg),cookie) | 
					
						
							|  |  |  |                     self.wfile.write(msg)                 | 
					
						
							| 
									
										
										
										
											2019-07-22 09:38:02 +00:00
										 |  |  |                     self.server.GETbusy=False | 
					
						
							|  |  |  |                     return | 
					
						
							| 
									
										
										
										
											2019-07-20 21:13:36 +00:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                 msg=json.dumps(following).encode('utf-8') | 
					
						
							|  |  |  |                 self._set_headers('application/json',len(msg),None) | 
					
						
							|  |  |  |                 self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-07-22 09:38:02 +00:00
										 |  |  |                 self.server.GETbusy=False | 
					
						
							| 
									
										
										
										
											2019-07-22 11:44:31 +00:00
										 |  |  |                 return | 
					
						
							| 
									
										
										
										
											2019-07-02 20:54:22 +00:00
										 |  |  |         followers=getFollowingFeed(self.server.baseDir,self.server.domain, \ | 
					
						
							|  |  |  |                                    self.server.port,self.path, \ | 
					
						
							| 
									
										
										
										
											2019-07-06 17:00:22 +00:00
										 |  |  |                                    self.server.httpPrefix, \ | 
					
						
							| 
									
										
										
										
											2019-07-19 08:40:51 +00:00
										 |  |  |                                    authorized,followsPerPage,'followers') | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  |         if followers: | 
					
						
							| 
									
										
										
										
											2019-08-24 11:23:12 +00:00
										 |  |  |             if self._requestHTTP(): | 
					
						
							| 
									
										
										
										
											2019-07-22 09:38:02 +00:00
										 |  |  |                 if 'page=' not in self.path: | 
					
						
							|  |  |  |                     # get a page of followers, not the summary | 
					
						
							|  |  |  |                     followers=getFollowingFeed(self.server.baseDir,self.server.domain, \ | 
					
						
							|  |  |  |                                                self.server.port,self.path+'?page=1', \ | 
					
						
							|  |  |  |                                                self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                                authorized,followsPerPage,'followers') | 
					
						
							|  |  |  |                 getPerson = personLookup(self.server.domain,self.path.replace('/followers',''), \ | 
					
						
							|  |  |  |                                          self.server.baseDir) | 
					
						
							|  |  |  |                 if getPerson: | 
					
						
							| 
									
										
										
										
											2019-07-22 14:09:21 +00:00
										 |  |  |                     if not self.server.session: | 
					
						
							|  |  |  |                         if self.server.debug: | 
					
						
							|  |  |  |                             print('DEBUG: creating new session') | 
					
						
							|  |  |  |                         self.server.session= \ | 
					
						
							|  |  |  |                             createSession(self.server.domain,self.server.port,self.server.useTor) | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                     msg=htmlProfile(self.server.projectVersion, \ | 
					
						
							|  |  |  |                                     self.server.baseDir, \ | 
					
						
							|  |  |  |                                     self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                     authorized, \ | 
					
						
							|  |  |  |                                     self.server.ocapAlways, \ | 
					
						
							|  |  |  |                                     getPerson,'followers', \ | 
					
						
							|  |  |  |                                     self.server.session, \ | 
					
						
							|  |  |  |                                     self.server.cachedWebfingers, \ | 
					
						
							|  |  |  |                                     self.server.personCache, \ | 
					
						
							|  |  |  |                                     followers).encode('utf-8') | 
					
						
							|  |  |  |                     self._set_headers('text/html',len(msg),cookie) | 
					
						
							|  |  |  |                     self.wfile.write(msg)                 | 
					
						
							| 
									
										
										
										
											2019-07-22 09:38:02 +00:00
										 |  |  |                     self.server.GETbusy=False | 
					
						
							|  |  |  |                     return | 
					
						
							| 
									
										
										
										
											2019-07-20 21:13:36 +00:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                 msg=json.dumps(followers).encode('utf-8') | 
					
						
							|  |  |  |                 self._set_headers('application/json',len(msg),None) | 
					
						
							|  |  |  |                 self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-07-01 14:30:48 +00:00
										 |  |  |             self.server.GETbusy=False | 
					
						
							| 
									
										
										
										
											2019-07-04 14:36:29 +00:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |         # look up a person | 
					
						
							| 
									
										
										
										
											2019-07-02 20:54:22 +00:00
										 |  |  |         getPerson = personLookup(self.server.domain,self.path, \ | 
					
						
							|  |  |  |                                  self.server.baseDir) | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |         if getPerson: | 
					
						
							| 
									
										
										
										
											2019-08-24 11:23:12 +00:00
										 |  |  |             if self._requestHTTP(): | 
					
						
							| 
									
										
										
										
											2019-07-22 14:09:21 +00:00
										 |  |  |                 if not self.server.session: | 
					
						
							|  |  |  |                     if self.server.debug: | 
					
						
							|  |  |  |                         print('DEBUG: creating new session') | 
					
						
							|  |  |  |                     self.server.session= \ | 
					
						
							|  |  |  |                         createSession(self.server.domain,self.server.port,self.server.useTor) | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                 msg=htmlProfile(self.server.projectVersion, \ | 
					
						
							|  |  |  |                                 self.server.baseDir, \ | 
					
						
							|  |  |  |                                 self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                 authorized, \ | 
					
						
							|  |  |  |                                 self.server.ocapAlways, \ | 
					
						
							|  |  |  |                                 getPerson,'posts', | 
					
						
							|  |  |  |                                 self.server.session, \ | 
					
						
							|  |  |  |                                 self.server.cachedWebfingers, \ | 
					
						
							|  |  |  |                                 self.server.personCache).encode('utf-8') | 
					
						
							|  |  |  |                 self._set_headers('text/html',len(msg),cookie) | 
					
						
							|  |  |  |                 self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-07-20 21:13:36 +00:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                 msg=json.dumps(getPerson).encode('utf-8') | 
					
						
							|  |  |  |                 self._set_headers('application/json',len(msg),None) | 
					
						
							|  |  |  |                 self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-07-01 14:30:48 +00:00
										 |  |  |             self.server.GETbusy=False | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |             return | 
					
						
							|  |  |  |         # check that a json file was requested | 
					
						
							|  |  |  |         if not self.path.endswith('.json'): | 
					
						
							| 
									
										
										
										
											2019-07-03 16:14:45 +00:00
										 |  |  |             if self.server.debug: | 
					
						
							|  |  |  |                 print('DEBUG: GET Not json: '+self.path+' '+self.server.baseDir) | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |             self._404() | 
					
						
							| 
									
										
										
										
											2019-07-01 14:30:48 +00:00
										 |  |  |             self.server.GETbusy=False | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |             return | 
					
						
							|  |  |  |         # check that the file exists | 
					
						
							| 
									
										
										
										
											2019-06-30 22:56:37 +00:00
										 |  |  |         filename=self.server.baseDir+self.path | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |         if os.path.isfile(filename): | 
					
						
							| 
									
										
										
										
											2019-07-03 19:15:42 +00:00
										 |  |  |             with open(filename, 'r', encoding='utf-8') as File: | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |                 content = File.read() | 
					
						
							|  |  |  |                 contentJson=json.loads(content) | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                 msg=json.dumps(contentJson).encode('utf-8') | 
					
						
							|  |  |  |                 self._set_headers('application/json',len(msg),None) | 
					
						
							|  |  |  |                 self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2019-07-03 16:14:45 +00:00
										 |  |  |             if self.server.debug: | 
					
						
							|  |  |  |                 print('DEBUG: GET Unknown file') | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |             self._404() | 
					
						
							| 
									
										
										
										
											2019-07-01 14:30:48 +00:00
										 |  |  |         self.server.GETbusy=False | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def do_HEAD(self): | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |         self._set_headers('application/json',0,None) | 
					
						
							| 
									
										
										
										
											2019-07-01 21:01:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-25 21:05:51 +00:00
										 |  |  |     def _receiveNewPost(self,authorized: bool,postType: str) -> int: | 
					
						
							| 
									
										
										
										
											2019-07-28 15:16:14 +00:00
										 |  |  |         # 0 = this is not a new post | 
					
						
							|  |  |  |         # 1 = new post success | 
					
						
							|  |  |  |         # -1 = new post failed | 
					
						
							|  |  |  |         # 2 = new post canceled | 
					
						
							| 
									
										
										
										
											2019-07-27 20:30:58 +00:00
										 |  |  |         if authorized and '/users/' in self.path and self.path.endswith('?'+postType):             | 
					
						
							|  |  |  |             if ' boundary=' in self.headers['Content-type']: | 
					
						
							|  |  |  |                 nickname=None | 
					
						
							|  |  |  |                 nicknameStr=self.path.split('/users/')[1] | 
					
						
							|  |  |  |                 if '/' in nicknameStr: | 
					
						
							|  |  |  |                     nickname=nicknameStr.split('/')[0] | 
					
						
							|  |  |  |                 else: | 
					
						
							| 
									
										
										
										
											2019-07-28 15:16:14 +00:00
										 |  |  |                     return -1 | 
					
						
							| 
									
										
										
										
											2019-07-27 20:30:58 +00:00
										 |  |  |                 length = int(self.headers['Content-length']) | 
					
						
							|  |  |  |                 if length>self.server.maxPostLength: | 
					
						
							|  |  |  |                     print('POST size too large') | 
					
						
							| 
									
										
										
										
											2019-07-28 15:16:14 +00:00
										 |  |  |                     return -1 | 
					
						
							| 
									
										
										
										
											2019-07-27 20:30:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 boundary=self.headers['Content-type'].split('boundary=')[1] | 
					
						
							|  |  |  |                 if ';' in boundary: | 
					
						
							|  |  |  |                     boundary=boundary.split(';')[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 # Note: we don't use cgi here because it's due to be deprecated | 
					
						
							|  |  |  |                 # in Python 3.8/3.10 | 
					
						
							|  |  |  |                 # Instead we use the multipart mime parser from the email module | 
					
						
							|  |  |  |                 postBytes=self.rfile.read(length) | 
					
						
							|  |  |  |                 msg = email.parser.BytesParser().parsebytes(postBytes) | 
					
						
							|  |  |  |                 # why don't we just use msg.is_multipart(), rather than splitting? | 
					
						
							|  |  |  |                 # TL;DR it doesn't work for this use case because we're not using | 
					
						
							|  |  |  |                 # email style encoding message/rfc822 | 
					
						
							|  |  |  |                 messageFields=msg.get_payload(decode=False).split(boundary) | 
					
						
							|  |  |  |                 fields={} | 
					
						
							| 
									
										
										
										
											2019-07-27 22:48:34 +00:00
										 |  |  |                 filename=None | 
					
						
							| 
									
										
										
										
											2019-08-30 15:50:20 +00:00
										 |  |  |                 attachmentMediaType=None | 
					
						
							| 
									
										
										
										
											2019-07-27 20:30:58 +00:00
										 |  |  |                 for f in messageFields: | 
					
						
							| 
									
										
										
										
											2019-07-28 13:30:19 +00:00
										 |  |  |                     if f=='--': | 
					
						
							|  |  |  |                         continue | 
					
						
							| 
									
										
										
										
											2019-07-27 20:30:58 +00:00
										 |  |  |                     if ' name="' in f: | 
					
						
							|  |  |  |                         postStr=f.split(' name="',1)[1] | 
					
						
							|  |  |  |                         if '"' in postStr: | 
					
						
							|  |  |  |                             postKey=postStr.split('"',1)[0] | 
					
						
							|  |  |  |                             postValueStr=postStr.split('"',1)[1] | 
					
						
							|  |  |  |                             if ';' not in postValueStr: | 
					
						
							|  |  |  |                                 if '\r\n' in postValueStr: | 
					
						
							|  |  |  |                                     postLines=postValueStr.split('\r\n')                                     | 
					
						
							|  |  |  |                                     postValue='' | 
					
						
							|  |  |  |                                     if len(postLines)>2: | 
					
						
							|  |  |  |                                         for line in range(2,len(postLines)-1): | 
					
						
							|  |  |  |                                             if line>2: | 
					
						
							|  |  |  |                                                 postValue+='\n' | 
					
						
							|  |  |  |                                             postValue+=postLines[line] | 
					
						
							|  |  |  |                                     fields[postKey]=postValue | 
					
						
							|  |  |  |                             else: | 
					
						
							|  |  |  |                                 # directly search the binary array for the beginning | 
					
						
							|  |  |  |                                 # of an image | 
					
						
							| 
									
										
										
										
											2019-08-30 17:35:57 +00:00
										 |  |  |                                 extensionList=['png','jpeg','gif','mp4','webm','ogv','mp3','ogg'] | 
					
						
							|  |  |  |                                 for extension in extensionList: | 
					
						
							|  |  |  |                                     searchStr=b'Content-Type: image/png' | 
					
						
							|  |  |  |                                     if extension=='jpeg': | 
					
						
							|  |  |  |                                         searchStr=b'Content-Type: image/jpeg' | 
					
						
							|  |  |  |                                     elif extension=='gif': | 
					
						
							|  |  |  |                                         searchStr=b'Content-Type: image/gif' | 
					
						
							|  |  |  |                                     elif extension=='mp4': | 
					
						
							|  |  |  |                                         searchStr=b'Content-Type: video/mp4' | 
					
						
							|  |  |  |                                     elif extension=='ogv': | 
					
						
							|  |  |  |                                         searchStr=b'Content-Type: video/ogv' | 
					
						
							|  |  |  |                                     elif extension=='mp3': | 
					
						
							|  |  |  |                                         searchStr=b'Content-Type: audio/mp3' | 
					
						
							|  |  |  |                                     elif extension=='ogg': | 
					
						
							|  |  |  |                                         searchStr=b'Content-Type: audio/ogg' | 
					
						
							|  |  |  |                                     imageLocation=postBytes.find(searchStr) | 
					
						
							|  |  |  |                                     filenameBase=self.server.baseDir+'/accounts/'+nickname+'@'+self.server.domain+'/upload' | 
					
						
							|  |  |  |                                     if imageLocation>-1: | 
					
						
							| 
									
										
										
										
											2019-08-30 17:16:01 +00:00
										 |  |  |                                         if extension=='jpeg': | 
					
						
							| 
									
										
										
										
											2019-08-30 17:35:57 +00:00
										 |  |  |                                             extension='jpg' | 
					
						
							|  |  |  |                                         filename=filenameBase+'.'+extension | 
					
						
							| 
									
										
										
										
											2019-08-30 18:17:43 +00:00
										 |  |  |                                         attachmentMediaType=searchStr.decode().split('/')[0].replace('Content-Type: ','') | 
					
						
							| 
									
										
										
										
											2019-08-30 17:35:57 +00:00
										 |  |  |                                         break | 
					
						
							| 
									
										
										
										
											2019-07-28 13:30:19 +00:00
										 |  |  |                                 if filename and imageLocation>-1: | 
					
						
							| 
									
										
										
										
											2019-07-27 20:30:58 +00:00
										 |  |  |                                     # locate the beginning of the image, after any | 
					
						
							|  |  |  |                                     # carriage returns | 
					
						
							| 
									
										
										
										
											2019-08-30 17:16:01 +00:00
										 |  |  |                                     startPos=imageLocation+len(searchStr) | 
					
						
							| 
									
										
										
										
											2019-07-27 20:30:58 +00:00
										 |  |  |                                     for offset in range(1,8): | 
					
						
							|  |  |  |                                         if postBytes[startPos+offset]!=10: | 
					
						
							|  |  |  |                                             if postBytes[startPos+offset]!=13: | 
					
						
							|  |  |  |                                                 startPos+=offset | 
					
						
							|  |  |  |                                                 break | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                                     fd = open(filename, 'wb') | 
					
						
							|  |  |  |                                     fd.write(postBytes[startPos:]) | 
					
						
							|  |  |  |                                     fd.close() | 
					
						
							| 
									
										
										
										
											2019-08-30 17:35:57 +00:00
										 |  |  |                                 else: | 
					
						
							|  |  |  |                                     filename=None | 
					
						
							| 
									
										
										
										
											2019-07-27 20:30:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-27 22:48:34 +00:00
										 |  |  |                 # send the post | 
					
						
							|  |  |  |                 if not fields.get('message'): | 
					
						
							| 
									
										
										
										
											2019-07-28 15:16:14 +00:00
										 |  |  |                     return -1 | 
					
						
							|  |  |  |                 if fields.get('submitPost'): | 
					
						
							|  |  |  |                     if fields['submitPost']!='Submit': | 
					
						
							|  |  |  |                         return -1 | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     return 2 | 
					
						
							| 
									
										
										
										
											2019-07-27 22:48:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 if not fields.get('imageDescription'): | 
					
						
							|  |  |  |                     fields['imageDescription']=None | 
					
						
							|  |  |  |                 if not fields.get('subject'): | 
					
						
							|  |  |  |                     fields['subject']=None | 
					
						
							|  |  |  |                 if not fields.get('replyTo'): | 
					
						
							|  |  |  |                     fields['replyTo']=None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if postType=='newpost': | 
					
						
							|  |  |  |                     messageJson= \ | 
					
						
							|  |  |  |                         createPublicPost(self.server.baseDir, \ | 
					
						
							|  |  |  |                                          nickname, \ | 
					
						
							|  |  |  |                                          self.server.domain,self.server.port, \ | 
					
						
							|  |  |  |                                          self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                          fields['message'],False,False,False, \ | 
					
						
							| 
									
										
										
										
											2019-08-30 15:50:20 +00:00
										 |  |  |                                          filename,attachmentMediaType,fields['imageDescription'],True, \ | 
					
						
							| 
									
										
										
										
											2019-07-27 22:48:34 +00:00
										 |  |  |                                          fields['replyTo'], fields['replyTo'],fields['subject']) | 
					
						
							|  |  |  |                     if messageJson: | 
					
						
							| 
									
										
										
										
											2019-07-28 13:30:19 +00:00
										 |  |  |                         self.postToNickname=nickname | 
					
						
							| 
									
										
										
										
											2019-08-02 18:57:06 +00:00
										 |  |  |                         if self._postToOutbox(messageJson): | 
					
						
							|  |  |  |                             populateReplies(self.server.baseDir, \ | 
					
						
							|  |  |  |                                             self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                             self.server.domainFull, \ | 
					
						
							|  |  |  |                                             messageJson, \ | 
					
						
							|  |  |  |                                             self.server.maxReplies, \ | 
					
						
							|  |  |  |                                             self.server.debug) | 
					
						
							| 
									
										
										
										
											2019-07-28 15:16:14 +00:00
										 |  |  |                             return 1 | 
					
						
							|  |  |  |                         else: | 
					
						
							|  |  |  |                             return -1 | 
					
						
							| 
									
										
										
										
											2019-07-27 22:48:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-28 11:08:14 +00:00
										 |  |  |                 if postType=='newunlisted': | 
					
						
							|  |  |  |                     messageJson= \ | 
					
						
							|  |  |  |                         createUnlistedPost(self.server.baseDir, \ | 
					
						
							|  |  |  |                                            nickname, \ | 
					
						
							|  |  |  |                                            self.server.domain,self.server.port, \ | 
					
						
							|  |  |  |                                            self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                            fields['message'],False,False,False, \ | 
					
						
							| 
									
										
										
										
											2019-08-30 15:50:20 +00:00
										 |  |  |                                            filename,attachmentMediaType,fields['imageDescription'],True, \ | 
					
						
							| 
									
										
										
										
											2019-07-28 11:08:14 +00:00
										 |  |  |                                            fields['replyTo'], fields['replyTo'],fields['subject']) | 
					
						
							|  |  |  |                     if messageJson: | 
					
						
							| 
									
										
										
										
											2019-07-28 13:30:19 +00:00
										 |  |  |                         self.postToNickname=nickname | 
					
						
							| 
									
										
										
										
											2019-07-28 15:16:14 +00:00
										 |  |  |                         if self._postToOutbox(messageJson): | 
					
						
							| 
									
										
										
										
											2019-08-02 18:04:31 +00:00
										 |  |  |                             populateReplies(self.server.baseDir, \ | 
					
						
							|  |  |  |                                             self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                             self.server.domain, \ | 
					
						
							|  |  |  |                                             messageJson, \ | 
					
						
							|  |  |  |                                             self.server.maxReplies, \ | 
					
						
							|  |  |  |                                             self.server.debug) | 
					
						
							| 
									
										
										
										
											2019-07-28 15:16:14 +00:00
										 |  |  |                             return 1 | 
					
						
							|  |  |  |                         else: | 
					
						
							|  |  |  |                             return -1 | 
					
						
							| 
									
										
										
										
											2019-07-28 11:08:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-27 22:48:34 +00:00
										 |  |  |                 if postType=='newfollowers': | 
					
						
							|  |  |  |                     messageJson= \ | 
					
						
							|  |  |  |                         createFollowersOnlyPost(self.server.baseDir, \ | 
					
						
							|  |  |  |                                                 nickname, \ | 
					
						
							|  |  |  |                                                 self.server.domain,self.server.port, \ | 
					
						
							|  |  |  |                                                 self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                                 fields['message'],True,False,False, \ | 
					
						
							| 
									
										
										
										
											2019-08-30 15:50:20 +00:00
										 |  |  |                                                 filename,attachmentMediaType,fields['imageDescription'],True, \ | 
					
						
							| 
									
										
										
										
											2019-07-27 22:48:34 +00:00
										 |  |  |                                                 fields['replyTo'], fields['replyTo'],fields['subject']) | 
					
						
							|  |  |  |                     if messageJson: | 
					
						
							| 
									
										
										
										
											2019-07-28 13:30:19 +00:00
										 |  |  |                         self.postToNickname=nickname | 
					
						
							| 
									
										
										
										
											2019-07-28 15:16:14 +00:00
										 |  |  |                         if self._postToOutbox(messageJson): | 
					
						
							| 
									
										
										
										
											2019-08-02 18:04:31 +00:00
										 |  |  |                             populateReplies(self.server.baseDir, \ | 
					
						
							|  |  |  |                                             self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                             self.server.domain, \ | 
					
						
							|  |  |  |                                             messageJson, \ | 
					
						
							|  |  |  |                                             self.server.maxReplies, \ | 
					
						
							|  |  |  |                                             self.server.debug) | 
					
						
							| 
									
										
										
										
											2019-07-28 15:16:14 +00:00
										 |  |  |                             return 1 | 
					
						
							|  |  |  |                         else: | 
					
						
							|  |  |  |                             return -1 | 
					
						
							| 
									
										
										
										
											2019-07-27 22:48:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 if postType=='newdm': | 
					
						
							| 
									
										
										
										
											2019-08-11 11:25:27 +00:00
										 |  |  |                     messageJson=None | 
					
						
							|  |  |  |                     if '@' in fields['message']: | 
					
						
							|  |  |  |                         messageJson= \ | 
					
						
							|  |  |  |                             createDirectMessagePost(self.server.baseDir, \ | 
					
						
							|  |  |  |                                                     nickname, \ | 
					
						
							|  |  |  |                                                     self.server.domain,self.server.port, \ | 
					
						
							|  |  |  |                                                     self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                                     fields['message'],True,False,False, \ | 
					
						
							| 
									
										
										
										
											2019-08-30 15:50:20 +00:00
										 |  |  |                                                     filename,attachmentMediaType, \ | 
					
						
							|  |  |  |                                                     fields['imageDescription'],True, \ | 
					
						
							| 
									
										
										
										
											2019-08-19 09:11:25 +00:00
										 |  |  |                                                     fields['replyTo'],fields['replyTo'], \ | 
					
						
							|  |  |  |                                                     fields['subject'], \ | 
					
						
							|  |  |  |                                                     self.server.debug) | 
					
						
							| 
									
										
										
										
											2019-07-27 22:48:34 +00:00
										 |  |  |                     if messageJson: | 
					
						
							| 
									
										
										
										
											2019-07-28 13:30:19 +00:00
										 |  |  |                         self.postToNickname=nickname | 
					
						
							| 
									
										
										
										
											2019-08-19 08:45:10 +00:00
										 |  |  |                         if self.server.debug: | 
					
						
							|  |  |  |                             print('DEBUG: new DM to '+str(messageJson['object']['to'])) | 
					
						
							| 
									
										
										
										
											2019-07-28 15:16:14 +00:00
										 |  |  |                         if self._postToOutbox(messageJson): | 
					
						
							| 
									
										
										
										
											2019-08-02 18:04:31 +00:00
										 |  |  |                             populateReplies(self.server.baseDir, \ | 
					
						
							|  |  |  |                                             self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                             self.server.domain, \ | 
					
						
							|  |  |  |                                             messageJson, \ | 
					
						
							|  |  |  |                                             self.server.maxReplies, \ | 
					
						
							|  |  |  |                                             self.server.debug) | 
					
						
							| 
									
										
										
										
											2019-07-28 15:16:14 +00:00
										 |  |  |                             return 1 | 
					
						
							|  |  |  |                         else: | 
					
						
							|  |  |  |                             return -1 | 
					
						
							| 
									
										
										
										
											2019-07-27 22:48:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-11 11:25:27 +00:00
										 |  |  |                 if postType=='newreport': | 
					
						
							| 
									
										
										
										
											2019-08-30 15:50:20 +00:00
										 |  |  |                     if attachmentMediaType: | 
					
						
							|  |  |  |                         if attachmentMediaType!='image': | 
					
						
							|  |  |  |                             return -1 | 
					
						
							| 
									
										
										
										
											2019-08-11 11:25:27 +00:00
										 |  |  |                     # So as to be sure that this only goes to moderators | 
					
						
							|  |  |  |                     # and not accounts being reported we disable any | 
					
						
							|  |  |  |                     # included fediverse addresses by replacing '@' with '-at-' | 
					
						
							|  |  |  |                     fields['message']=fields['message'].replace('@','-at-') | 
					
						
							|  |  |  |                     messageJson= \ | 
					
						
							|  |  |  |                         createReportPost(self.server.baseDir, \ | 
					
						
							|  |  |  |                                          nickname, \ | 
					
						
							|  |  |  |                                          self.server.domain,self.server.port, \ | 
					
						
							|  |  |  |                                          self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                          fields['message'],True,False,False, \ | 
					
						
							| 
									
										
										
										
											2019-08-30 15:50:20 +00:00
										 |  |  |                                          filename,attachmentMediaType, \ | 
					
						
							|  |  |  |                                          fields['imageDescription'],True, \ | 
					
						
							| 
									
										
										
										
											2019-08-11 11:25:27 +00:00
										 |  |  |                                          self.server.debug,fields['subject']) | 
					
						
							|  |  |  |                     if messageJson: | 
					
						
							|  |  |  |                         self.postToNickname=nickname | 
					
						
							|  |  |  |                         if self._postToOutbox(messageJson): | 
					
						
							|  |  |  |                             return 1 | 
					
						
							|  |  |  |                         else: | 
					
						
							|  |  |  |                             return -1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-27 22:48:34 +00:00
										 |  |  |                 if postType=='newshare': | 
					
						
							| 
									
										
										
										
											2019-07-28 08:34:49 +00:00
										 |  |  |                     if not fields.get('itemType'): | 
					
						
							| 
									
										
										
										
											2019-08-30 15:50:20 +00:00
										 |  |  |                         return -1 | 
					
						
							| 
									
										
										
										
											2019-07-28 08:34:49 +00:00
										 |  |  |                     if not fields.get('category'): | 
					
						
							| 
									
										
										
										
											2019-08-30 15:50:20 +00:00
										 |  |  |                         return -1 | 
					
						
							| 
									
										
										
										
											2019-07-28 08:34:49 +00:00
										 |  |  |                     if not fields.get('location'): | 
					
						
							| 
									
										
										
										
											2019-08-30 15:50:20 +00:00
										 |  |  |                         return -1 | 
					
						
							| 
									
										
										
										
											2019-07-28 08:34:49 +00:00
										 |  |  |                     if not fields.get('duration'): | 
					
						
							| 
									
										
										
										
											2019-08-30 15:50:20 +00:00
										 |  |  |                         return -1 | 
					
						
							|  |  |  |                     if attachmentMediaType: | 
					
						
							|  |  |  |                         if attachmentMediaType!='image': | 
					
						
							|  |  |  |                             return -1 | 
					
						
							| 
									
										
										
										
											2019-07-28 08:34:49 +00:00
										 |  |  |                     addShare(self.server.baseDir, \ | 
					
						
							|  |  |  |                              self.server.httpPrefix, \ | 
					
						
							|  |  |  |                              nickname, \ | 
					
						
							|  |  |  |                              self.server.domain,self.server.port, \ | 
					
						
							|  |  |  |                              fields['subject'], \ | 
					
						
							|  |  |  |                              fields['message'], \ | 
					
						
							|  |  |  |                              filename, \ | 
					
						
							|  |  |  |                              fields['itemType'], \ | 
					
						
							|  |  |  |                              fields['category'], \ | 
					
						
							|  |  |  |                              fields['location'], \ | 
					
						
							|  |  |  |                              fields['duration'], | 
					
						
							|  |  |  |                              self.server.debug) | 
					
						
							| 
									
										
										
										
											2019-08-25 21:12:04 +00:00
										 |  |  |                     if filename: | 
					
						
							|  |  |  |                         if os.path.isfile(filename): | 
					
						
							|  |  |  |                             os.remove(filename) | 
					
						
							| 
									
										
										
										
											2019-07-28 13:30:19 +00:00
										 |  |  |                     self.postToNickname=nickname | 
					
						
							| 
									
										
										
										
											2019-08-25 21:13:57 +00:00
										 |  |  |                     return 1 | 
					
						
							| 
									
										
										
										
											2019-07-28 15:16:14 +00:00
										 |  |  |             return -1 | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             return 0 | 
					
						
							| 
									
										
										
										
											2019-07-27 20:30:58 +00:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |     def do_POST(self): | 
					
						
							| 
									
										
										
										
											2019-08-20 11:30:41 +00:00
										 |  |  |         if not self.server.session: | 
					
						
							|  |  |  |             self.server.session= \ | 
					
						
							|  |  |  |                 createSession(self.server.domain,self.server.port,self.server.useTor) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-04 17:56:25 +00:00
										 |  |  |         if self.server.debug: | 
					
						
							| 
									
										
										
										
											2019-07-06 17:00:22 +00:00
										 |  |  |             print('DEBUG: POST to from '+self.server.baseDir+ \ | 
					
						
							|  |  |  |                   ' path: '+self.path+' busy: '+ \ | 
					
						
							|  |  |  |                   str(self.server.POSTbusy)) | 
					
						
							| 
									
										
										
										
											2019-07-01 14:30:48 +00:00
										 |  |  |         if self.server.POSTbusy: | 
					
						
							|  |  |  |             currTimePOST=int(time.time()) | 
					
						
							| 
									
										
										
										
											2019-08-14 22:24:51 +00:00
										 |  |  |             if currTimePOST-self.server.lastPOST==0: | 
					
						
							| 
									
										
										
										
											2019-06-29 17:28:43 +00:00
										 |  |  |                 self.send_response(429) | 
					
						
							| 
									
										
										
										
											2019-06-29 17:27:32 +00:00
										 |  |  |                 self.end_headers() | 
					
						
							| 
									
										
										
										
											2019-07-01 14:30:48 +00:00
										 |  |  |                 return               | 
					
						
							|  |  |  |             self.server.lastPOST=currTimePOST | 
					
						
							| 
									
										
										
										
											2019-07-29 16:13:48 +00:00
										 |  |  |              | 
					
						
							| 
									
										
										
										
											2019-07-01 14:30:48 +00:00
										 |  |  |         self.server.POSTbusy=True | 
					
						
							| 
									
										
										
										
											2019-07-01 11:48:54 +00:00
										 |  |  |         if not self.headers.get('Content-type'): | 
					
						
							| 
									
										
										
										
											2019-07-03 16:14:45 +00:00
										 |  |  |             print('Content-type header missing') | 
					
						
							| 
									
										
										
										
											2019-07-01 11:48:54 +00:00
										 |  |  |             self.send_response(400) | 
					
						
							|  |  |  |             self.end_headers() | 
					
						
							| 
									
										
										
										
											2019-07-01 14:30:48 +00:00
										 |  |  |             self.server.POSTbusy=False | 
					
						
							| 
									
										
										
										
											2019-07-01 11:48:54 +00:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-07-03 16:14:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-03 21:37:46 +00:00
										 |  |  |         # remove any trailing slashes from the path | 
					
						
							| 
									
										
										
										
											2019-07-31 09:00:44 +00:00
										 |  |  |         if not self.path.endswith('confirm'): | 
					
						
							|  |  |  |             self.path=self.path.replace('/outbox/','/outbox').replace('/inbox/','/inbox').replace('/shares/','/shares').replace('/sharedInbox/','/sharedInbox') | 
					
						
							| 
									
										
										
										
											2019-07-03 21:37:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-29 16:13:48 +00:00
										 |  |  |         cookie=None | 
					
						
							|  |  |  |         if self.headers.get('Cookie'): | 
					
						
							|  |  |  |             cookie=self.headers['Cookie'] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-27 20:30:58 +00:00
										 |  |  |         # check authorization | 
					
						
							|  |  |  |         authorized = self._isAuthorized() | 
					
						
							|  |  |  |         if authorized: | 
					
						
							|  |  |  |             if self.server.debug: | 
					
						
							|  |  |  |                 print('POST Authorization granted') | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             if self.server.debug: | 
					
						
							|  |  |  |                 print('POST Not authorized') | 
					
						
							| 
									
										
										
										
											2019-07-29 16:13:48 +00:00
										 |  |  |                 print(str(self.headers)) | 
					
						
							| 
									
										
										
										
											2019-07-27 20:30:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-03 21:37:46 +00:00
										 |  |  |         # if this is a POST to teh outbox then check authentication | 
					
						
							|  |  |  |         self.outboxAuthenticated=False | 
					
						
							|  |  |  |         self.postToNickname=None | 
					
						
							| 
									
										
										
										
											2019-07-24 22:38:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if self.path.startswith('/login'): | 
					
						
							| 
									
										
										
										
											2019-07-25 10:56:24 +00:00
										 |  |  |             # get the contents of POST containing login credentials | 
					
						
							|  |  |  |             length = int(self.headers['Content-length']) | 
					
						
							|  |  |  |             if length>512: | 
					
						
							|  |  |  |                 print('Login failed - credentials too long') | 
					
						
							|  |  |  |                 self.send_response(401) | 
					
						
							|  |  |  |                 self.end_headers() | 
					
						
							|  |  |  |                 self.server.POSTbusy=False | 
					
						
							|  |  |  |                 return                 | 
					
						
							| 
									
										
										
										
											2019-08-15 14:50:47 +00:00
										 |  |  |             loginParams=self.rfile.read(length).decode('utf-8') | 
					
						
							| 
									
										
										
										
											2019-08-08 13:38:33 +00:00
										 |  |  |             loginNickname,loginPassword,register=htmlGetLoginCredentials(loginParams,self.server.lastLoginTime) | 
					
						
							| 
									
										
										
										
											2019-07-24 22:38:42 +00:00
										 |  |  |             if loginNickname: | 
					
						
							|  |  |  |                 self.server.lastLoginTime=int(time.time()) | 
					
						
							| 
									
										
										
										
											2019-08-08 13:38:33 +00:00
										 |  |  |                 if register: | 
					
						
							|  |  |  |                     if not registerAccount(self.server.baseDir,self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                            self.server.domain,self.server.port, \ | 
					
						
							|  |  |  |                                            loginNickname,loginPassword): | 
					
						
							|  |  |  |                         self.server.POSTbusy=False | 
					
						
							|  |  |  |                         self._redirect_headers('/login',cookie) | 
					
						
							|  |  |  |                         return | 
					
						
							| 
									
										
										
										
											2019-07-24 22:38:42 +00:00
										 |  |  |                 authHeader=createBasicAuthHeader(loginNickname,loginPassword) | 
					
						
							|  |  |  |                 if not authorizeBasic(self.server.baseDir,'/users/'+loginNickname+'/outbox',authHeader,False): | 
					
						
							| 
									
										
										
										
											2019-07-25 10:56:24 +00:00
										 |  |  |                     print('Login failed: '+loginNickname) | 
					
						
							| 
									
										
										
										
											2019-07-25 14:24:42 +00:00
										 |  |  |                     # remove any token | 
					
						
							|  |  |  |                     if self.server.tokens.get(loginNickname): | 
					
						
							|  |  |  |                         del self.server.tokensLookup[self.server.tokens[loginNickname]] | 
					
						
							|  |  |  |                         del self.server.tokens[loginNickname] | 
					
						
							|  |  |  |                         del self.server.salts[loginNickname] | 
					
						
							| 
									
										
										
										
											2019-07-25 19:22:19 +00:00
										 |  |  |                     self.send_response(303) | 
					
						
							| 
									
										
										
										
											2019-08-15 14:50:47 +00:00
										 |  |  |                     self.send_header('Content-Length', '0') | 
					
						
							| 
									
										
										
										
											2019-07-25 14:24:42 +00:00
										 |  |  |                     self.send_header('Set-Cookie', 'epicyon=; SameSite=Strict') | 
					
						
							| 
									
										
										
										
											2019-07-25 19:22:19 +00:00
										 |  |  |                     self.send_header('Location', '/login') | 
					
						
							|  |  |  |                     self.end_headers()                     | 
					
						
							| 
									
										
										
										
											2019-07-24 22:38:42 +00:00
										 |  |  |                     self.server.POSTbusy=False | 
					
						
							|  |  |  |                     return | 
					
						
							| 
									
										
										
										
											2019-07-25 10:56:24 +00:00
										 |  |  |                 else: | 
					
						
							| 
									
										
										
										
											2019-08-13 09:24:55 +00:00
										 |  |  |                     if isSuspended(self.server.baseDir,loginNickname): | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                         msg=htmlSuspended(self.server.baseDir).encode('utf-8') | 
					
						
							|  |  |  |                         self._login_headers('text/html',len(msg)) | 
					
						
							|  |  |  |                         self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-08-13 09:24:55 +00:00
										 |  |  |                         self.server.POSTbusy=False | 
					
						
							|  |  |  |                         return                         | 
					
						
							| 
									
										
										
										
											2019-07-25 10:56:24 +00:00
										 |  |  |                     # login success - redirect with authorization | 
					
						
							|  |  |  |                     print('Login success: '+loginNickname) | 
					
						
							|  |  |  |                     self.send_response(303) | 
					
						
							| 
									
										
										
										
											2019-07-25 14:30:12 +00:00
										 |  |  |                     # This produces a deterministic token based on nick+password+salt | 
					
						
							|  |  |  |                     # But notice that the salt is ephemeral, so a server reboot changes them. | 
					
						
							|  |  |  |                     # This allows you to be logged in on two or more devices with the | 
					
						
							|  |  |  |                     # same token, but also ensures that if an adversary obtains the token | 
					
						
							|  |  |  |                     # then rebooting the server is sufficient to thwart them, without | 
					
						
							|  |  |  |                     # any password changes. | 
					
						
							| 
									
										
										
										
											2019-07-25 14:24:42 +00:00
										 |  |  |                     if not self.server.salts.get(loginNickname): | 
					
						
							|  |  |  |                         self.server.salts[loginNickname]=createPassword(32) | 
					
						
							| 
									
										
										
										
											2019-07-25 16:50:48 +00:00
										 |  |  |                     self.server.tokens[loginNickname]=sha256((loginNickname+loginPassword+self.server.salts[loginNickname]).encode('utf-8')).hexdigest() | 
					
						
							| 
									
										
										
										
											2019-07-25 14:24:42 +00:00
										 |  |  |                     self.server.tokensLookup[self.server.tokens[loginNickname]]=loginNickname | 
					
						
							|  |  |  |                     self.send_header('Set-Cookie', 'epicyon='+self.server.tokens[loginNickname]+'; SameSite=Strict') | 
					
						
							| 
									
										
										
										
											2019-07-25 19:23:52 +00:00
										 |  |  |                     self.send_header('Location', '/users/'+loginNickname+'/inbox') | 
					
						
							| 
									
										
										
										
											2019-08-15 14:50:47 +00:00
										 |  |  |                     self.send_header('Content-Length', '0') | 
					
						
							| 
									
										
										
										
											2019-07-25 10:56:24 +00:00
										 |  |  |                     self.end_headers() | 
					
						
							|  |  |  |                     self.server.POSTbusy=False | 
					
						
							|  |  |  |                     return | 
					
						
							| 
									
										
										
										
											2019-07-24 22:38:42 +00:00
										 |  |  |             self.send_response(200) | 
					
						
							|  |  |  |             self.end_headers() | 
					
						
							|  |  |  |             self.server.POSTbusy=False | 
					
						
							| 
									
										
										
										
											2019-08-13 10:48:16 +00:00
										 |  |  |             return             | 
					
						
							| 
									
										
										
										
											2019-07-24 22:38:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-02 09:52:12 +00:00
										 |  |  |         # update of profile/avatar from web interface | 
					
						
							|  |  |  |         if authorized and self.path.endswith('/profiledata'): | 
					
						
							|  |  |  |             if ' boundary=' in self.headers['Content-type']: | 
					
						
							|  |  |  |                 boundary=self.headers['Content-type'].split('boundary=')[1] | 
					
						
							|  |  |  |                 if ';' in boundary: | 
					
						
							|  |  |  |                     boundary=boundary.split(';')[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 actorStr=self.path.replace('/profiledata','').replace('/editprofile','') | 
					
						
							|  |  |  |                 nickname=getNicknameFromActor(actorStr) | 
					
						
							|  |  |  |                 if not nickname: | 
					
						
							|  |  |  |                     self._redirect_headers(actorStr,cookie) | 
					
						
							|  |  |  |                     self.server.POSTbusy=False | 
					
						
							|  |  |  |                     return | 
					
						
							|  |  |  |                 length = int(self.headers['Content-length']) | 
					
						
							| 
									
										
										
										
											2019-08-26 21:51:10 +00:00
										 |  |  |                 if length>self.server.maxPostLength: | 
					
						
							| 
									
										
										
										
											2019-08-26 19:43:52 +00:00
										 |  |  |                     print('Maximum profile data length exceeded '+str(length)) | 
					
						
							|  |  |  |                     self._redirect_headers(actorStr,cookie) | 
					
						
							|  |  |  |                     self.server.POSTbusy=False | 
					
						
							|  |  |  |                     return | 
					
						
							| 
									
										
										
										
											2019-08-26 21:15:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-26 21:22:23 +00:00
										 |  |  |                 postBytes=self.rfile.read(length) | 
					
						
							| 
									
										
										
										
											2019-08-26 21:19:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-02 09:52:12 +00:00
										 |  |  |                 msg = email.parser.BytesParser().parsebytes(postBytes)                 | 
					
						
							|  |  |  |                 messageFields=msg.get_payload(decode=False).split(boundary) | 
					
						
							|  |  |  |                 fields={} | 
					
						
							|  |  |  |                 filename=None | 
					
						
							|  |  |  |                 lastImageLocation=0 | 
					
						
							|  |  |  |                 for f in messageFields: | 
					
						
							|  |  |  |                     if f=='--': | 
					
						
							|  |  |  |                         continue | 
					
						
							|  |  |  |                     if ' name="' in f: | 
					
						
							|  |  |  |                         postStr=f.split(' name="',1)[1] | 
					
						
							|  |  |  |                         if '"' in postStr: | 
					
						
							|  |  |  |                             postKey=postStr.split('"',1)[0] | 
					
						
							|  |  |  |                             postValueStr=postStr.split('"',1)[1] | 
					
						
							|  |  |  |                             if ';' not in postValueStr: | 
					
						
							|  |  |  |                                 if '\r\n' in postValueStr: | 
					
						
							|  |  |  |                                     postLines=postValueStr.split('\r\n')                                     | 
					
						
							|  |  |  |                                     postValue='' | 
					
						
							|  |  |  |                                     if len(postLines)>2: | 
					
						
							|  |  |  |                                         for line in range(2,len(postLines)-1): | 
					
						
							|  |  |  |                                             if line>2: | 
					
						
							|  |  |  |                                                 postValue+='\n' | 
					
						
							|  |  |  |                                             postValue+=postLines[line] | 
					
						
							|  |  |  |                                     fields[postKey]=postValue | 
					
						
							|  |  |  |                             else: | 
					
						
							| 
									
										
										
										
											2019-08-02 10:10:41 +00:00
										 |  |  |                                 if 'filename="' not in postStr: | 
					
						
							|  |  |  |                                     continue | 
					
						
							|  |  |  |                                 filenameStr=postStr.split('filename="')[1] | 
					
						
							|  |  |  |                                 if '"' not in filenameStr: | 
					
						
							|  |  |  |                                     continue | 
					
						
							|  |  |  |                                 postImageFilename=filenameStr.split('"')[0] | 
					
						
							|  |  |  |                                 if '.' not in postImageFilename: | 
					
						
							|  |  |  |                                     continue | 
					
						
							| 
									
										
										
										
											2019-08-02 09:52:12 +00:00
										 |  |  |                                 # directly search the binary array for the beginning | 
					
						
							|  |  |  |                                 # of an image | 
					
						
							|  |  |  |                                 searchStr=b'Content-Type: image/png'                                 | 
					
						
							|  |  |  |                                 imageLocation=postBytes.find(searchStr,lastImageLocation) | 
					
						
							|  |  |  |                                 filenameBase=self.server.baseDir+'/accounts/'+nickname+'@'+self.server.domain+'/'+postKey | 
					
						
							| 
									
										
										
										
											2019-08-02 09:55:45 +00:00
										 |  |  |                                 # Note: a .temp extension is used here so that at no time is | 
					
						
							|  |  |  |                                 # an image with metadata publicly exposed, even for a few mS | 
					
						
							| 
									
										
										
										
											2019-08-02 09:52:12 +00:00
										 |  |  |                                 if imageLocation>-1: | 
					
						
							|  |  |  |                                     filename=filenameBase+'.png.temp' | 
					
						
							|  |  |  |                                 else:         | 
					
						
							|  |  |  |                                     searchStr=b'Content-Type: image/jpeg' | 
					
						
							|  |  |  |                                     imageLocation=postBytes.find(searchStr,lastImageLocation) | 
					
						
							|  |  |  |                                     if imageLocation>-1:                                     | 
					
						
							|  |  |  |                                         filename=filenameBase+'.jpg.temp' | 
					
						
							|  |  |  |                                     else:      | 
					
						
							|  |  |  |                                         searchStr=b'Content-Type: image/gif' | 
					
						
							|  |  |  |                                         imageLocation=postBytes.find(searchStr,lastImageLocation) | 
					
						
							|  |  |  |                                         if imageLocation>-1:                                     | 
					
						
							|  |  |  |                                             filename=filenameBase+'.gif.temp' | 
					
						
							|  |  |  |                                 if filename and imageLocation>-1: | 
					
						
							|  |  |  |                                     # locate the beginning of the image, after any | 
					
						
							|  |  |  |                                     # carriage returns | 
					
						
							|  |  |  |                                     startPos=imageLocation+len(searchStr) | 
					
						
							|  |  |  |                                     for offset in range(1,8): | 
					
						
							|  |  |  |                                         if postBytes[startPos+offset]!=10: | 
					
						
							|  |  |  |                                             if postBytes[startPos+offset]!=13: | 
					
						
							|  |  |  |                                                 startPos+=offset | 
					
						
							|  |  |  |                                                 break | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-02 09:55:45 +00:00
										 |  |  |                                     # look for the end of the image | 
					
						
							| 
									
										
										
										
											2019-08-02 09:52:12 +00:00
										 |  |  |                                     imageLocationEnd=postBytes.find(b'-------',imageLocation+1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                                     fd = open(filename, 'wb') | 
					
						
							|  |  |  |                                     if imageLocationEnd>-1: | 
					
						
							|  |  |  |                                         fd.write(postBytes[startPos:][:imageLocationEnd-startPos]) | 
					
						
							|  |  |  |                                     else: | 
					
						
							|  |  |  |                                         fd.write(postBytes[startPos:]) | 
					
						
							|  |  |  |                                     fd.close() | 
					
						
							| 
									
										
										
										
											2019-08-02 09:55:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |                                     # remove exif/metadata | 
					
						
							| 
									
										
										
										
											2019-08-02 09:52:12 +00:00
										 |  |  |                                     removeMetaData(filename,filename.replace('.temp','')) | 
					
						
							|  |  |  |                                     os.remove(filename) | 
					
						
							|  |  |  |                                     lastImageLocation=imageLocation+1 | 
					
						
							|  |  |  |                                      | 
					
						
							|  |  |  |                 actorFilename=self.server.baseDir+'/accounts/'+nickname+'@'+self.server.domain+'.json' | 
					
						
							|  |  |  |                 if os.path.isfile(actorFilename): | 
					
						
							|  |  |  |                     with open(actorFilename, 'r') as fp: | 
					
						
							|  |  |  |                         actorJson=commentjson.load(fp) | 
					
						
							|  |  |  |                         actorChanged=False | 
					
						
							| 
									
										
										
										
											2019-08-09 08:46:38 +00:00
										 |  |  |                         skillCtr=1 | 
					
						
							|  |  |  |                         newSkills={} | 
					
						
							|  |  |  |                         while skillCtr<10: | 
					
						
							|  |  |  |                             skillName=fields.get('skillName'+str(skillCtr)) | 
					
						
							|  |  |  |                             if not skillName: | 
					
						
							|  |  |  |                                 skillCtr+=1 | 
					
						
							|  |  |  |                                 continue | 
					
						
							|  |  |  |                             skillValue=fields.get('skillValue'+str(skillCtr)) | 
					
						
							|  |  |  |                             if not skillValue: | 
					
						
							|  |  |  |                                 skillCtr+=1 | 
					
						
							|  |  |  |                                 continue | 
					
						
							|  |  |  |                             if not actorJson['skills'].get(skillName): | 
					
						
							|  |  |  |                                 actorChanged=True | 
					
						
							|  |  |  |                             else: | 
					
						
							|  |  |  |                                 if actorJson['skills'][skillName]!=int(skillValue): | 
					
						
							|  |  |  |                                     actorChanged=True | 
					
						
							|  |  |  |                             newSkills[skillName]=int(skillValue) | 
					
						
							|  |  |  |                             skillCtr+=1 | 
					
						
							|  |  |  |                         if len(actorJson['skills'].items())!=len(newSkills.items()): | 
					
						
							|  |  |  |                             actorChanged=True | 
					
						
							|  |  |  |                         actorJson['skills']=newSkills | 
					
						
							| 
									
										
										
										
											2019-08-22 18:36:07 +00:00
										 |  |  |                         if fields.get('displayNickname'): | 
					
						
							|  |  |  |                             if fields['displayNickname']!=actorJson['name']: | 
					
						
							|  |  |  |                                 actorJson['name']=fields['displayNickname'] | 
					
						
							| 
									
										
										
										
											2019-08-02 09:52:12 +00:00
										 |  |  |                                 actorChanged=True | 
					
						
							|  |  |  |                         if fields.get('bio'): | 
					
						
							|  |  |  |                             if fields['bio']!=actorJson['summary']: | 
					
						
							| 
									
										
										
										
											2019-08-09 16:18:00 +00:00
										 |  |  |                                 actorTags={} | 
					
						
							| 
									
										
										
										
											2019-08-02 09:52:12 +00:00
										 |  |  |                                 actorJson['summary']= \ | 
					
						
							| 
									
										
										
										
											2019-08-09 09:09:21 +00:00
										 |  |  |                                     addHtmlTags(self.server.baseDir, \ | 
					
						
							| 
									
										
										
										
											2019-08-02 09:52:12 +00:00
										 |  |  |                                                 self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                                 nickname, \ | 
					
						
							| 
									
										
										
										
											2019-08-09 16:18:00 +00:00
										 |  |  |                                                 self.server.domainFull, \ | 
					
						
							|  |  |  |                                                 fields['bio'],[],actorTags) | 
					
						
							|  |  |  |                                 if actorTags: | 
					
						
							|  |  |  |                                     actorJson['tag']=[] | 
					
						
							|  |  |  |                                     for tagName,tag in actorTags.items(): | 
					
						
							|  |  |  |                                         actorJson['tag'].append(tag) | 
					
						
							| 
									
										
										
										
											2019-08-02 09:52:12 +00:00
										 |  |  |                                 actorChanged=True | 
					
						
							| 
									
										
										
										
											2019-08-12 21:20:47 +00:00
										 |  |  |                         if fields.get('moderators'): | 
					
						
							|  |  |  |                             adminNickname=getConfigParam(self.server.baseDir,'admin') | 
					
						
							|  |  |  |                             if self.path.startswith('/users/'+adminNickname+'/'): | 
					
						
							|  |  |  |                                 moderatorsFile=self.server.baseDir+'/accounts/moderators.txt' | 
					
						
							|  |  |  |                                 clearModeratorStatus(self.server.baseDir) | 
					
						
							|  |  |  |                                 if ',' in fields['moderators']: | 
					
						
							|  |  |  |                                     # if the list was given as comma separated | 
					
						
							|  |  |  |                                     modFile=open(moderatorsFile,"w+") | 
					
						
							|  |  |  |                                     for modNick in fields['moderators'].split(','): | 
					
						
							|  |  |  |                                         modNick=modNick.strip() | 
					
						
							|  |  |  |                                         if os.path.isdir(self.server.baseDir+'/accounts/'+modNick+'@'+self.server.domain): | 
					
						
							|  |  |  |                                             modFile.write(modNick+'\n') | 
					
						
							|  |  |  |                                     modFile.close() | 
					
						
							|  |  |  |                                     for modNick in fields['moderators'].split(','): | 
					
						
							|  |  |  |                                         modNick=modNick.strip() | 
					
						
							|  |  |  |                                         if os.path.isdir(self.server.baseDir+'/accounts/'+modNick+'@'+self.server.domain): | 
					
						
							|  |  |  |                                             setRole(self.server.baseDir,modNick,self.server.domain,'instance','moderator') | 
					
						
							|  |  |  |                                 else: | 
					
						
							|  |  |  |                                     # nicknames on separate lines | 
					
						
							|  |  |  |                                     modFile=open(moderatorsFile,"w+") | 
					
						
							|  |  |  |                                     for modNick in fields['moderators'].split('\n'): | 
					
						
							|  |  |  |                                         modNick=modNick.strip() | 
					
						
							|  |  |  |                                         if os.path.isdir(self.server.baseDir+'/accounts/'+modNick+'@'+self.server.domain): | 
					
						
							|  |  |  |                                             modFile.write(modNick+'\n') | 
					
						
							|  |  |  |                                     modFile.close() | 
					
						
							|  |  |  |                                     for modNick in fields['moderators'].split('\n'): | 
					
						
							|  |  |  |                                         modNick=modNick.strip() | 
					
						
							|  |  |  |                                         if os.path.isdir(self.server.baseDir+'/accounts/'+modNick+'@'+self.server.domain): | 
					
						
							|  |  |  |                                             setRole(self.server.baseDir,modNick,self.server.domain,'instance','moderator') | 
					
						
							|  |  |  |                                          | 
					
						
							| 
									
										
										
										
											2019-08-07 20:13:44 +00:00
										 |  |  |                         approveFollowers=False | 
					
						
							| 
									
										
										
										
											2019-08-02 09:52:12 +00:00
										 |  |  |                         if fields.get('approveFollowers'): | 
					
						
							| 
									
										
										
										
											2019-08-07 20:13:44 +00:00
										 |  |  |                             if fields['approveFollowers']=='on': | 
					
						
							| 
									
										
										
										
											2019-08-02 09:52:12 +00:00
										 |  |  |                                 approveFollowers=True | 
					
						
							| 
									
										
										
										
											2019-08-07 20:13:44 +00:00
										 |  |  |                         if approveFollowers!=actorJson['manuallyApprovesFollowers']: | 
					
						
							|  |  |  |                             actorJson['manuallyApprovesFollowers']=approveFollowers | 
					
						
							|  |  |  |                             actorChanged=True | 
					
						
							|  |  |  |                         if fields.get('isBot'): | 
					
						
							|  |  |  |                             if fields['isBot']=='on': | 
					
						
							|  |  |  |                                 if actorJson['type']!='Service': | 
					
						
							|  |  |  |                                     actorJson['type']='Service' | 
					
						
							|  |  |  |                                     actorChanged=True | 
					
						
							|  |  |  |                         else: | 
					
						
							|  |  |  |                             if actorJson['type']!='Person': | 
					
						
							|  |  |  |                                 actorJson['type']='Person' | 
					
						
							| 
									
										
										
										
											2019-08-02 09:52:12 +00:00
										 |  |  |                                 actorChanged=True | 
					
						
							| 
									
										
										
										
											2019-08-02 11:43:14 +00:00
										 |  |  |                         # save filtered words list | 
					
						
							|  |  |  |                         filterFilename=self.server.baseDir+'/accounts/'+nickname+'@'+self.server.domain+'/filters.txt' | 
					
						
							|  |  |  |                         if fields.get('filteredWords'): | 
					
						
							|  |  |  |                             with open(filterFilename, "w") as filterfile: | 
					
						
							|  |  |  |                                 filterfile.write(fields['filteredWords']) | 
					
						
							|  |  |  |                         else: | 
					
						
							|  |  |  |                             if os.path.isfile(filterFilename): | 
					
						
							|  |  |  |                                 os.remove(filterFilename) | 
					
						
							|  |  |  |                         # save blocked accounts list | 
					
						
							|  |  |  |                         blockedFilename=self.server.baseDir+'/accounts/'+nickname+'@'+self.server.domain+'/blocking.txt' | 
					
						
							|  |  |  |                         if fields.get('blocked'): | 
					
						
							|  |  |  |                             with open(blockedFilename, "w") as blockedfile: | 
					
						
							|  |  |  |                                 blockedfile.write(fields['blocked']) | 
					
						
							|  |  |  |                         else: | 
					
						
							|  |  |  |                             if os.path.isfile(blockedFilename): | 
					
						
							|  |  |  |                                 os.remove(blockedFilename) | 
					
						
							| 
									
										
										
										
											2019-08-02 12:11:32 +00:00
										 |  |  |                         # save allowed instances list | 
					
						
							|  |  |  |                         allowedInstancesFilename=self.server.baseDir+'/accounts/'+nickname+'@'+self.server.domain+'/allowedinstances.txt' | 
					
						
							|  |  |  |                         if fields.get('allowedInstances'): | 
					
						
							|  |  |  |                             with open(allowedInstancesFilename, "w") as allowedInstancesFile: | 
					
						
							|  |  |  |                                 allowedInstancesFile.write(fields['allowedInstances']) | 
					
						
							|  |  |  |                         else: | 
					
						
							|  |  |  |                             if os.path.isfile(allowedInstancesFilename): | 
					
						
							|  |  |  |                                 os.remove(allowedInstancesFilename) | 
					
						
							| 
									
										
										
										
											2019-08-02 11:43:14 +00:00
										 |  |  |                         # save actor json file within accounts | 
					
						
							| 
									
										
										
										
											2019-08-02 09:52:12 +00:00
										 |  |  |                         if actorChanged: | 
					
						
							|  |  |  |                             with open(actorFilename, 'w') as fp: | 
					
						
							|  |  |  |                                 commentjson.dump(actorJson, fp, indent=4, sort_keys=False) | 
					
						
							| 
									
										
										
										
											2019-08-22 14:50:47 +00:00
										 |  |  |                             # also copy to the actors cache and personCache in memory | 
					
						
							| 
									
										
										
										
											2019-08-22 15:14:05 +00:00
										 |  |  |                             storePersonInCache(self.server.baseDir,actorJson['id'],actorJson,self.server.personCache) | 
					
						
							| 
									
										
										
										
											2019-08-22 14:50:47 +00:00
										 |  |  |                             actorCacheFilename=self.server.baseDir+'/cache/actors/'+actorJson['id'].replace('/','#')+'.json' | 
					
						
							|  |  |  |                             with open(actorCacheFilename, 'w') as fp: | 
					
						
							|  |  |  |                                 commentjson.dump(actorJson, fp, indent=4, sort_keys=False)                             | 
					
						
							| 
									
										
										
										
											2019-08-22 16:15:02 +00:00
										 |  |  |                             # send actor update to followers | 
					
						
							|  |  |  |                             updateActorJson={ | 
					
						
							|  |  |  |                                 'type': 'Update', | 
					
						
							|  |  |  |                                 'actor': actorJson['id'], | 
					
						
							|  |  |  |                                 'to': ['https://www.w3.org/ns/activitystreams#Public'], | 
					
						
							| 
									
										
										
										
											2019-08-22 16:21:21 +00:00
										 |  |  |                                 'cc': [actorJson['id']+'/followers'], | 
					
						
							| 
									
										
										
										
											2019-08-22 16:15:02 +00:00
										 |  |  |                                 'object': actorJson | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                             self.postToNickname=nickname | 
					
						
							|  |  |  |                             self._postToOutbox(updateActorJson) | 
					
						
							| 
									
										
										
										
											2019-08-02 09:52:12 +00:00
										 |  |  |             self._redirect_headers(actorStr,cookie) | 
					
						
							|  |  |  |             self.server.POSTbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-13 10:48:16 +00:00
										 |  |  |         # moderator action buttons | 
					
						
							|  |  |  |         if authorized and '/users/' in self.path and \ | 
					
						
							| 
									
										
										
										
											2019-08-13 11:59:38 +00:00
										 |  |  |            self.path.endswith('/moderationaction'): | 
					
						
							|  |  |  |             actorStr=self.path.replace('/moderationaction','') | 
					
						
							| 
									
										
										
										
											2019-08-13 10:48:16 +00:00
										 |  |  |             length = int(self.headers['Content-length']) | 
					
						
							|  |  |  |             moderationParams=self.rfile.read(length).decode('utf-8') | 
					
						
							|  |  |  |             print('moderationParams: '+moderationParams) | 
					
						
							| 
									
										
										
										
											2019-08-13 11:59:38 +00:00
										 |  |  |             if '&' in moderationParams: | 
					
						
							|  |  |  |                 moderationText=None | 
					
						
							|  |  |  |                 moderationButton=None | 
					
						
							|  |  |  |                 for moderationStr in moderationParams.split('&'): | 
					
						
							| 
									
										
										
										
											2019-08-13 13:58:48 +00:00
										 |  |  |                     print('moderationStr: '+moderationStr) | 
					
						
							|  |  |  |                     if moderationStr.startswith('moderationAction'): | 
					
						
							| 
									
										
										
										
											2019-08-13 11:59:38 +00:00
										 |  |  |                         if '=' in moderationStr: | 
					
						
							|  |  |  |                             moderationText=moderationStr.split('=')[1].strip() | 
					
						
							|  |  |  |                             moderationText=moderationText.replace('+',' ').replace('%40','@').replace('%3A',':').replace('%23','#').strip() | 
					
						
							| 
									
										
										
										
											2019-08-13 17:25:39 +00:00
										 |  |  |                     elif moderationStr.startswith('submitInfo'): | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                         msg=htmlModerationInfo(self.server.baseDir).encode('utf-8') | 
					
						
							|  |  |  |                         self._login_headers('text/html',len(msg)) | 
					
						
							|  |  |  |                         self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-08-13 17:25:39 +00:00
										 |  |  |                         self.server.POSTbusy=False | 
					
						
							|  |  |  |                         return                         | 
					
						
							| 
									
										
										
										
											2019-08-13 11:59:38 +00:00
										 |  |  |                     elif moderationStr.startswith('submitBlock'): | 
					
						
							|  |  |  |                         moderationButton='block' | 
					
						
							|  |  |  |                     elif moderationStr.startswith('submitUnblock'): | 
					
						
							|  |  |  |                         moderationButton='unblock' | 
					
						
							|  |  |  |                     elif moderationStr.startswith('submitSuspend'): | 
					
						
							|  |  |  |                         moderationButton='suspend' | 
					
						
							|  |  |  |                     elif moderationStr.startswith('submitUnsuspend'): | 
					
						
							|  |  |  |                         moderationButton='unsuspend' | 
					
						
							|  |  |  |                     elif moderationStr.startswith('submitRemove'): | 
					
						
							|  |  |  |                         moderationButton='remove' | 
					
						
							|  |  |  |                 if moderationButton and moderationText: | 
					
						
							| 
									
										
										
										
											2019-08-13 13:58:48 +00:00
										 |  |  |                     if self.server.debug: | 
					
						
							|  |  |  |                         print('moderationButton: '+moderationButton) | 
					
						
							|  |  |  |                         print('moderationText: '+moderationText) | 
					
						
							| 
									
										
										
										
											2019-08-13 11:59:38 +00:00
										 |  |  |                     nickname=moderationText | 
					
						
							|  |  |  |                     if nickname.startswith('http') or \ | 
					
						
							|  |  |  |                        nickname.startswith('dat'): | 
					
						
							|  |  |  |                         nickname=getNicknameFromActor(nickname) | 
					
						
							|  |  |  |                     if '@' in nickname: | 
					
						
							|  |  |  |                         nickname=nickname.split('@')[0] | 
					
						
							|  |  |  |                     if moderationButton=='suspend': | 
					
						
							|  |  |  |                         suspendAccount(self.server.baseDir,nickname,self.server.salts) | 
					
						
							|  |  |  |                     if moderationButton=='unsuspend': | 
					
						
							|  |  |  |                         unsuspendAccount(self.server.baseDir,nickname) | 
					
						
							| 
									
										
										
										
											2019-08-13 15:45:47 +00:00
										 |  |  |                     if moderationButton=='block': | 
					
						
							| 
									
										
										
										
											2019-08-13 16:39:43 +00:00
										 |  |  |                         fullBlockDomain=None | 
					
						
							|  |  |  |                         if moderationText.startswith('http') or \ | 
					
						
							|  |  |  |                            moderationText.startswith('dat'): | 
					
						
							|  |  |  |                             blockDomain,blockPort=getDomainFromActor(moderationText) | 
					
						
							|  |  |  |                             fullBlockDomain=blockDomain | 
					
						
							|  |  |  |                             if blockPort: | 
					
						
							|  |  |  |                                 if blockPort!=80 and blockPort!=443: | 
					
						
							| 
									
										
										
										
											2019-08-16 20:35:11 +00:00
										 |  |  |                                     if ':' not in blockDomain: | 
					
						
							|  |  |  |                                         fullBlockDomain=blockDomain+':'+str(blockPort) | 
					
						
							| 
									
										
										
										
											2019-08-13 16:39:43 +00:00
										 |  |  |                         if '@' in moderationText: | 
					
						
							|  |  |  |                             fullBlockDomain=moderationText.split('@')[1] | 
					
						
							| 
									
										
										
										
											2019-08-14 10:32:15 +00:00
										 |  |  |                         if fullBlockDomain or nickname.startswith('#'): | 
					
						
							| 
									
										
										
										
											2019-08-13 16:39:43 +00:00
										 |  |  |                             addGlobalBlock(self.server.baseDir, \ | 
					
						
							|  |  |  |                                            nickname,fullBlockDomain) | 
					
						
							| 
									
										
										
										
											2019-08-13 15:45:47 +00:00
										 |  |  |                     if moderationButton=='unblock': | 
					
						
							| 
									
										
										
										
											2019-08-13 16:39:43 +00:00
										 |  |  |                         fullBlockDomain=None | 
					
						
							|  |  |  |                         if moderationText.startswith('http') or \ | 
					
						
							|  |  |  |                            moderationText.startswith('dat'): | 
					
						
							|  |  |  |                             blockDomain,blockPort=getDomainFromActor(moderationText) | 
					
						
							|  |  |  |                             fullBlockDomain=blockDomain | 
					
						
							|  |  |  |                             if blockPort: | 
					
						
							|  |  |  |                                 if blockPort!=80 and blockPort!=443: | 
					
						
							| 
									
										
										
										
											2019-08-16 20:35:11 +00:00
										 |  |  |                                     if ':' not in blockDomain: | 
					
						
							|  |  |  |                                         fullBlockDomain=blockDomain+':'+str(blockPort) | 
					
						
							| 
									
										
										
										
											2019-08-13 16:39:43 +00:00
										 |  |  |                         if '@' in moderationText: | 
					
						
							|  |  |  |                             fullBlockDomain=moderationText.split('@')[1] | 
					
						
							| 
									
										
										
										
											2019-08-14 10:32:15 +00:00
										 |  |  |                         if fullBlockDomain or nickname.startswith('#'): | 
					
						
							| 
									
										
										
										
											2019-08-13 16:39:43 +00:00
										 |  |  |                             removeGlobalBlock(self.server.baseDir, \ | 
					
						
							|  |  |  |                                               nickname,fullBlockDomain) | 
					
						
							| 
									
										
										
										
											2019-08-13 13:58:48 +00:00
										 |  |  |                     if moderationButton=='remove': | 
					
						
							|  |  |  |                         if '/statuses/' not in moderationText: | 
					
						
							|  |  |  |                             removeAccount(self.server.baseDir, \ | 
					
						
							|  |  |  |                                           nickname, \ | 
					
						
							|  |  |  |                                           self.server.domain, \ | 
					
						
							|  |  |  |                                           self.server.port) | 
					
						
							|  |  |  |                         else: | 
					
						
							| 
									
										
										
										
											2019-08-13 15:03:34 +00:00
										 |  |  |                             # remove a post or thread                             | 
					
						
							| 
									
										
										
										
											2019-08-13 13:58:48 +00:00
										 |  |  |                             postFilename= \ | 
					
						
							|  |  |  |                                 locatePost(self.server.baseDir, \ | 
					
						
							|  |  |  |                                            nickname,self.server.domain, \ | 
					
						
							|  |  |  |                                            moderationText) | 
					
						
							| 
									
										
										
										
											2019-08-13 15:03:34 +00:00
										 |  |  |                             if postFilename: | 
					
						
							|  |  |  |                                 if canRemovePost(self.server.baseDir, \ | 
					
						
							|  |  |  |                                                  nickname, \ | 
					
						
							|  |  |  |                                                  self.server.domain, \ | 
					
						
							|  |  |  |                                                  self.server.port, \ | 
					
						
							|  |  |  |                                                  moderationText):                                 | 
					
						
							|  |  |  |                                     deletePost(self.server.baseDir, \ | 
					
						
							|  |  |  |                                                self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                                nickname,self.server.omain, \ | 
					
						
							|  |  |  |                                                postFilename, \ | 
					
						
							|  |  |  |                                                self.server.debug) | 
					
						
							| 
									
										
										
										
											2019-08-13 10:48:16 +00:00
										 |  |  |             self._redirect_headers(actorStr+'/moderation',cookie) | 
					
						
							|  |  |  |             self.server.POSTbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-19 20:01:29 +00:00
										 |  |  |         searchForEmoji=False | 
					
						
							| 
									
										
										
										
											2019-08-19 20:11:38 +00:00
										 |  |  |         if self.path.endswith('/searchhandleemoji'): | 
					
						
							| 
									
										
										
										
											2019-08-19 20:01:29 +00:00
										 |  |  |             searchForEmoji=True | 
					
						
							|  |  |  |             self.path=self.path.replace('/searchhandleemoji','/searchhandle') | 
					
						
							| 
									
										
										
										
											2019-08-19 20:11:38 +00:00
										 |  |  |             if self.server.debug: | 
					
						
							|  |  |  |                 print('DEBUG: searching for emoji') | 
					
						
							|  |  |  |                 print('authorized: '+str(authorized)) | 
					
						
							| 
									
										
										
										
											2019-08-19 20:01:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-14 09:45:51 +00:00
										 |  |  |         # a search was made | 
					
						
							| 
									
										
										
										
											2019-08-19 20:13:21 +00:00
										 |  |  |         if (authorized or searchForEmoji) and \ | 
					
						
							| 
									
										
										
										
											2019-08-14 09:45:51 +00:00
										 |  |  |            (self.path.endswith('/searchhandle') or '/searchhandle?page=' in self.path): | 
					
						
							|  |  |  |             # get the page number | 
					
						
							|  |  |  |             pageNumber=1 | 
					
						
							|  |  |  |             if '/searchhandle?page=' in self.path: | 
					
						
							|  |  |  |                 pageNumberStr=self.path.split('/searchhandle?page=')[1] | 
					
						
							|  |  |  |                 if pageNumberStr.isdigit(): | 
					
						
							|  |  |  |                     pageNumber=int(pageNumberStr) | 
					
						
							|  |  |  |                 self.path=self.path.split('?page=')[0] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-26 10:33:31 +00:00
										 |  |  |             actorStr=self.server.httpPrefix+'://'+self.server.domainFull+self.path.replace('/searchhandle','') | 
					
						
							| 
									
										
										
										
											2019-07-30 22:34:04 +00:00
										 |  |  |             length = int(self.headers['Content-length']) | 
					
						
							|  |  |  |             searchParams=self.rfile.read(length).decode('utf-8') | 
					
						
							|  |  |  |             if 'searchtext=' in searchParams: | 
					
						
							|  |  |  |                 searchStr=searchParams.split('searchtext=')[1] | 
					
						
							|  |  |  |                 if '&' in searchStr: | 
					
						
							|  |  |  |                     searchStr=searchStr.split('&')[0] | 
					
						
							| 
									
										
										
										
											2019-08-21 16:45:36 +00:00
										 |  |  |                 searchStr=searchStr.replace('+',' ').replace('%40','@').replace('%3A',':').replace('%23','#').replace('%2F','/').strip() | 
					
						
							| 
									
										
										
										
											2019-08-21 16:42:00 +00:00
										 |  |  |                 if self.server.debug: | 
					
						
							|  |  |  |                     print('searchStr: '+searchStr) | 
					
						
							| 
									
										
										
										
											2019-08-19 20:01:29 +00:00
										 |  |  |                 if searchForEmoji: | 
					
						
							|  |  |  |                     searchStr=':'+searchStr+':' | 
					
						
							| 
									
										
										
										
											2019-08-13 21:32:18 +00:00
										 |  |  |                 if searchStr.startswith('#'):       | 
					
						
							| 
									
										
										
										
											2019-08-10 10:54:52 +00:00
										 |  |  |                     # hashtag search | 
					
						
							|  |  |  |                     hashtagStr= \ | 
					
						
							|  |  |  |                         htmlHashtagSearch(self.server.baseDir,searchStr[1:],1, \ | 
					
						
							|  |  |  |                                           maxPostsInFeed,self.server.session, \ | 
					
						
							|  |  |  |                                           self.server.cachedWebfingers, \ | 
					
						
							| 
									
										
										
										
											2019-08-14 20:12:27 +00:00
										 |  |  |                                           self.server.personCache, \ | 
					
						
							|  |  |  |                                           self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                           self.server.projectVersion) | 
					
						
							| 
									
										
										
										
											2019-08-10 10:54:52 +00:00
										 |  |  |                     if hashtagStr: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                         msg=hashtagStr.encode('utf-8') | 
					
						
							|  |  |  |                         self._login_headers('text/html',len(msg)) | 
					
						
							|  |  |  |                         self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-08-10 10:54:52 +00:00
										 |  |  |                         self.server.POSTbusy=False | 
					
						
							|  |  |  |                         return | 
					
						
							| 
									
										
										
										
											2019-08-27 22:50:40 +00:00
										 |  |  |                 elif searchStr.startswith('*'):       | 
					
						
							|  |  |  |                     # skill search | 
					
						
							|  |  |  |                     searchStr=searchStr.replace('*','').strip() | 
					
						
							|  |  |  |                     skillStr= \ | 
					
						
							| 
									
										
										
										
											2019-08-27 23:02:41 +00:00
										 |  |  |                         htmlSkillsSearch(self.server.baseDir,searchStr, \ | 
					
						
							| 
									
										
										
										
											2019-08-28 09:59:19 +00:00
										 |  |  |                                          self.server.instanceOnlySkillsSearch, \ | 
					
						
							| 
									
										
										
										
											2019-08-28 10:11:06 +00:00
										 |  |  |                                          64) | 
					
						
							| 
									
										
										
										
											2019-08-27 22:50:40 +00:00
										 |  |  |                     if skillStr: | 
					
						
							|  |  |  |                         msg=skillStr.encode('utf-8') | 
					
						
							|  |  |  |                         self._login_headers('text/html',len(msg)) | 
					
						
							|  |  |  |                         self.wfile.write(msg) | 
					
						
							|  |  |  |                         self.server.POSTbusy=False | 
					
						
							|  |  |  |                         return | 
					
						
							| 
									
										
										
										
											2019-08-13 21:32:18 +00:00
										 |  |  |                 elif '@' in searchStr: | 
					
						
							| 
									
										
										
										
											2019-08-10 10:54:52 +00:00
										 |  |  |                     # profile search | 
					
						
							| 
									
										
										
										
											2019-07-30 22:34:04 +00:00
										 |  |  |                     nickname=getNicknameFromActor(self.path) | 
					
						
							|  |  |  |                     if not self.server.session: | 
					
						
							|  |  |  |                         self.server.session= \ | 
					
						
							| 
									
										
										
										
											2019-08-14 09:45:51 +00:00
										 |  |  |                             createSession(self.server.domain, \ | 
					
						
							|  |  |  |                                           self.server.port, \ | 
					
						
							|  |  |  |                                           self.server.useTor) | 
					
						
							| 
									
										
										
										
											2019-07-30 22:34:04 +00:00
										 |  |  |                     profileStr= \ | 
					
						
							|  |  |  |                         htmlProfileAfterSearch(self.server.baseDir, \ | 
					
						
							|  |  |  |                                                self.path.replace('/searchhandle',''), \ | 
					
						
							|  |  |  |                                                self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                                nickname, \ | 
					
						
							|  |  |  |                                                self.server.domain,self.server.port, \ | 
					
						
							|  |  |  |                                                searchStr, \ | 
					
						
							|  |  |  |                                                self.server.session, \ | 
					
						
							|  |  |  |                                                self.server.cachedWebfingers, \ | 
					
						
							|  |  |  |                                                self.server.personCache, \ | 
					
						
							| 
									
										
										
										
											2019-08-14 20:12:27 +00:00
										 |  |  |                                                self.server.debug, \ | 
					
						
							|  |  |  |                                                self.server.projectVersion) | 
					
						
							| 
									
										
										
										
											2019-07-30 22:34:04 +00:00
										 |  |  |                     if profileStr: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                         msg=profileStr.encode('utf-8') | 
					
						
							|  |  |  |                         self._login_headers('text/html',len(msg)) | 
					
						
							| 
									
										
										
										
											2019-08-19 19:02:28 +00:00
										 |  |  |                         self.wfile.write(msg) | 
					
						
							|  |  |  |                         self.server.POSTbusy=False | 
					
						
							|  |  |  |                         return | 
					
						
							|  |  |  |                 elif searchStr.startswith(':') or \ | 
					
						
							|  |  |  |                      searchStr.lower().strip('\n').endswith(' emoji'): | 
					
						
							|  |  |  |                     # eg. "cat emoji" | 
					
						
							|  |  |  |                     if searchStr.lower().strip('\n').endswith(' emoji'): | 
					
						
							|  |  |  |                         searchStr=searchStr.lower().strip('\n').replace(' emoji','') | 
					
						
							|  |  |  |                     # emoji search | 
					
						
							|  |  |  |                     emojiStr= \ | 
					
						
							|  |  |  |                         htmlSearchEmoji(self.server.baseDir,searchStr) | 
					
						
							|  |  |  |                     if emojiStr: | 
					
						
							| 
									
										
										
										
											2019-08-19 19:06:54 +00:00
										 |  |  |                         msg=emojiStr.encode('utf-8') | 
					
						
							| 
									
										
										
										
											2019-08-19 19:02:28 +00:00
										 |  |  |                         self._login_headers('text/html',len(msg)) | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                         self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-07-30 22:34:04 +00:00
										 |  |  |                         self.server.POSTbusy=False | 
					
						
							|  |  |  |                         return | 
					
						
							| 
									
										
										
										
											2019-08-13 21:32:18 +00:00
										 |  |  |                 else: | 
					
						
							|  |  |  |                     # shared items search | 
					
						
							|  |  |  |                     sharedItemsStr= \ | 
					
						
							| 
									
										
										
										
											2019-08-14 09:45:51 +00:00
										 |  |  |                         htmlSearchSharedItems(self.server.baseDir, \ | 
					
						
							|  |  |  |                                               searchStr,pageNumber, \ | 
					
						
							| 
									
										
										
										
											2019-08-25 21:59:42 +00:00
										 |  |  |                                               maxPostsInFeed, \ | 
					
						
							|  |  |  |                                               self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                               self.server.domainFull, \ | 
					
						
							|  |  |  |                                               actorStr) | 
					
						
							| 
									
										
										
										
											2019-08-13 21:32:18 +00:00
										 |  |  |                     if sharedItemsStr: | 
					
						
							| 
									
										
										
										
											2019-08-15 13:20:09 +00:00
										 |  |  |                         msg=sharedItemsStr.encode('utf-8') | 
					
						
							|  |  |  |                         self._login_headers('text/html',len(msg)) | 
					
						
							|  |  |  |                         self.wfile.write(msg) | 
					
						
							| 
									
										
										
										
											2019-08-13 21:32:18 +00:00
										 |  |  |                         self.server.POSTbusy=False | 
					
						
							|  |  |  |                         return | 
					
						
							| 
									
										
										
										
											2019-08-26 10:36:00 +00:00
										 |  |  |             self._redirect_headers(actorStr+'/inbox',cookie) | 
					
						
							| 
									
										
										
										
											2019-07-30 22:34:04 +00:00
										 |  |  |             self.server.POSTbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-26 09:31:45 +00:00
										 |  |  |         # removes a shared item | 
					
						
							|  |  |  |         if authorized and self.path.endswith('/rmshare'): | 
					
						
							|  |  |  |             originPathStr=self.path.split('/rmshare')[0] | 
					
						
							|  |  |  |             length = int(self.headers['Content-length']) | 
					
						
							|  |  |  |             removeShareConfirmParams=self.rfile.read(length).decode('utf-8') | 
					
						
							|  |  |  |             if '&submitYes=' in removeShareConfirmParams: | 
					
						
							|  |  |  |                 removeShareConfirmParams=removeShareConfirmParams.replace('%3A',':').replace('%2F','/') | 
					
						
							|  |  |  |                 shareActor=removeShareConfirmParams.split('actor=')[1] | 
					
						
							|  |  |  |                 if '&' in shareActor: | 
					
						
							|  |  |  |                     shareActor=shareActor.split('&')[0] | 
					
						
							|  |  |  |                 shareName=removeShareConfirmParams.split('shareName=')[1] | 
					
						
							|  |  |  |                 if '&' in shareName: | 
					
						
							|  |  |  |                     shareName=shareName.split('&')[0] | 
					
						
							|  |  |  |                 shareNickname=getNicknameFromActor(shareActor) | 
					
						
							|  |  |  |                 shareDomain,sharePort=getDomainFromActor(shareActor) | 
					
						
							|  |  |  |                 removeShare(self.server.baseDir,shareNickname,shareDomain,shareName) | 
					
						
							| 
									
										
										
										
											2019-08-26 09:33:17 +00:00
										 |  |  |             self._redirect_headers(originPathStr+'/inbox',cookie) | 
					
						
							| 
									
										
										
										
											2019-08-26 09:31:45 +00:00
										 |  |  |             self.server.POSTbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-27 12:47:11 +00:00
										 |  |  |         # removes a post | 
					
						
							|  |  |  |         if authorized and self.path.endswith('/rmpost'): | 
					
						
							|  |  |  |             originPathStr=self.path.split('/rmpost')[0] | 
					
						
							|  |  |  |             length = int(self.headers['Content-length']) | 
					
						
							|  |  |  |             removePostConfirmParams=self.rfile.read(length).decode('utf-8') | 
					
						
							|  |  |  |             if '&submitYes=' in removePostConfirmParams: | 
					
						
							|  |  |  |                 removePostConfirmParams=removePostConfirmParams.replace('%3A',':').replace('%2F','/') | 
					
						
							|  |  |  |                 removeMessageId=removePostConfirmParams.split('messageId=')[1] | 
					
						
							|  |  |  |                 if '&' in removeMessageId: | 
					
						
							|  |  |  |                     removeMessageId=removeMessageId.split('&')[0] | 
					
						
							|  |  |  |                 if '/statuses/' in removeMessageId: | 
					
						
							|  |  |  |                     removePostActor=removeMessageId.split('/statuses/')[0] | 
					
						
							| 
									
										
										
										
											2019-08-27 12:49:53 +00:00
										 |  |  |                 if originPathStr in removePostActor: | 
					
						
							|  |  |  |                     deleteJson= { | 
					
						
							|  |  |  |                         "@context": "https://www.w3.org/ns/activitystreams", | 
					
						
							|  |  |  |                         'actor': removePostActor, | 
					
						
							|  |  |  |                         'object': removeMessageId, | 
					
						
							|  |  |  |                         'to': ['https://www.w3.org/ns/activitystreams#Public',removePostActor], | 
					
						
							|  |  |  |                         'cc': [removePostActor+'/followers'], | 
					
						
							|  |  |  |                         'type': 'Delete' | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     if self.server.debug: | 
					
						
							|  |  |  |                         pprint(deleteJson) | 
					
						
							| 
									
										
										
										
											2019-08-27 13:27:46 +00:00
										 |  |  |                     self.postToNickname=getNicknameFromActor(removePostActor) | 
					
						
							| 
									
										
										
										
											2019-08-27 12:49:53 +00:00
										 |  |  |                     self._postToOutbox(deleteJson)                     | 
					
						
							| 
									
										
										
										
											2019-08-27 12:47:11 +00:00
										 |  |  |             self._redirect_headers(originPathStr+'/outbox',cookie) | 
					
						
							|  |  |  |             self.server.POSTbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-29 16:13:48 +00:00
										 |  |  |         # decision to follow in the web interface is confirmed | 
					
						
							| 
									
										
										
										
											2019-07-29 20:36:26 +00:00
										 |  |  |         if authorized and self.path.endswith('/followconfirm'): | 
					
						
							| 
									
										
										
										
											2019-07-29 16:13:48 +00:00
										 |  |  |             originPathStr=self.path.split('/followconfirm')[0] | 
					
						
							|  |  |  |             followerNickname=getNicknameFromActor(originPathStr) | 
					
						
							|  |  |  |             length = int(self.headers['Content-length']) | 
					
						
							|  |  |  |             followConfirmParams=self.rfile.read(length).decode('utf-8') | 
					
						
							|  |  |  |             if '&submitYes=' in followConfirmParams: | 
					
						
							|  |  |  |                 followingActor=followConfirmParams.replace('%3A',':').replace('%2F','/').split('actor=')[1] | 
					
						
							|  |  |  |                 if '&' in followingActor: | 
					
						
							|  |  |  |                     followingActor=followingActor.split('&')[0] | 
					
						
							|  |  |  |                 followingNickname=getNicknameFromActor(followingActor) | 
					
						
							|  |  |  |                 followingDomain,followingPort=getDomainFromActor(followingActor) | 
					
						
							|  |  |  |                 if followerNickname==followingNickname and \ | 
					
						
							|  |  |  |                    followingDomain==self.server.domain and \ | 
					
						
							|  |  |  |                    followingPort==self.server.port: | 
					
						
							|  |  |  |                     if self.server.debug: | 
					
						
							|  |  |  |                         print('You cannot follow yourself!') | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     if self.server.debug: | 
					
						
							|  |  |  |                         print('Sending follow request from '+followerNickname+' to '+followingActor) | 
					
						
							|  |  |  |                     sendFollowRequest(self.server.session, \ | 
					
						
							|  |  |  |                                       self.server.baseDir, \ | 
					
						
							|  |  |  |                                       followerNickname, \ | 
					
						
							|  |  |  |                                       self.server.domain,self.server.port, \ | 
					
						
							|  |  |  |                                       self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                       followingNickname, \ | 
					
						
							|  |  |  |                                       followingDomain, \ | 
					
						
							|  |  |  |                                       followingPort,self.server.httpPrefix, \ | 
					
						
							|  |  |  |                                       False,self.server.federationList, \ | 
					
						
							|  |  |  |                                       self.server.sendThreads, \ | 
					
						
							|  |  |  |                                       self.server.postLog, \ | 
					
						
							|  |  |  |                                       self.server.cachedWebfingers, \ | 
					
						
							|  |  |  |                                       self.server.personCache, \ | 
					
						
							| 
									
										
										
										
											2019-08-14 20:12:27 +00:00
										 |  |  |                                       self.server.debug, \ | 
					
						
							|  |  |  |                                       self.server.projectVersion) | 
					
						
							| 
									
										
										
										
											2019-07-29 20:36:26 +00:00
										 |  |  |             self._redirect_headers(originPathStr,cookie) | 
					
						
							|  |  |  |             self.server.POSTbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # decision to unfollow in the web interface is confirmed | 
					
						
							|  |  |  |         if authorized and self.path.endswith('/unfollowconfirm'): | 
					
						
							|  |  |  |             originPathStr=self.path.split('/unfollowconfirm')[0] | 
					
						
							|  |  |  |             followerNickname=getNicknameFromActor(originPathStr) | 
					
						
							|  |  |  |             length = int(self.headers['Content-length']) | 
					
						
							|  |  |  |             followConfirmParams=self.rfile.read(length).decode('utf-8') | 
					
						
							|  |  |  |             if '&submitYes=' in followConfirmParams: | 
					
						
							|  |  |  |                 followingActor=followConfirmParams.replace('%3A',':').replace('%2F','/').split('actor=')[1] | 
					
						
							|  |  |  |                 if '&' in followingActor: | 
					
						
							|  |  |  |                     followingActor=followingActor.split('&')[0] | 
					
						
							|  |  |  |                 followingNickname=getNicknameFromActor(followingActor) | 
					
						
							|  |  |  |                 followingDomain,followingPort=getDomainFromActor(followingActor) | 
					
						
							|  |  |  |                 if followerNickname==followingNickname and \ | 
					
						
							|  |  |  |                    followingDomain==self.server.domain and \ | 
					
						
							|  |  |  |                    followingPort==self.server.port: | 
					
						
							|  |  |  |                     if self.server.debug: | 
					
						
							|  |  |  |                         print('You cannot unfollow yourself!') | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     if self.server.debug: | 
					
						
							|  |  |  |                         print(followerNickname+' stops following '+followingActor) | 
					
						
							|  |  |  |                     followActor=self.server.httpPrefix+'://'+self.server.domainFull+'/users/'+followerNickname | 
					
						
							| 
									
										
										
										
											2019-08-18 09:39:12 +00:00
										 |  |  |                     statusNumber,published = getStatusNumber() | 
					
						
							|  |  |  |                     followId=followActor+'/statuses/'+str(statusNumber) | 
					
						
							| 
									
										
										
										
											2019-07-29 20:36:26 +00:00
										 |  |  |                     unfollowJson = { | 
					
						
							| 
									
										
										
										
											2019-08-16 21:52:11 +00:00
										 |  |  |                         '@context': 'https://www.w3.org/ns/activitystreams', | 
					
						
							|  |  |  |                         'id': followId+'/undo', | 
					
						
							| 
									
										
										
										
											2019-07-29 20:36:26 +00:00
										 |  |  |                         'type': 'Undo', | 
					
						
							|  |  |  |                         'actor': followActor, | 
					
						
							|  |  |  |                         'object': { | 
					
						
							| 
									
										
										
										
											2019-08-16 21:52:11 +00:00
										 |  |  |                             'id': followId, | 
					
						
							| 
									
										
										
										
											2019-07-29 20:36:26 +00:00
										 |  |  |                             'type': 'Follow', | 
					
						
							|  |  |  |                             'actor': followActor, | 
					
						
							| 
									
										
										
										
											2019-08-16 21:52:11 +00:00
										 |  |  |                             'object': followingActor | 
					
						
							| 
									
										
										
										
											2019-07-29 20:36:26 +00:00
										 |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2019-08-08 08:54:41 +00:00
										 |  |  |                     pathUsersSection=self.path.split('/users/')[1] | 
					
						
							|  |  |  |                     self.postToNickname=pathUsersSection.split('/')[0] | 
					
						
							| 
									
										
										
										
											2019-07-29 20:36:26 +00:00
										 |  |  |                     self._postToOutbox(unfollowJson) | 
					
						
							| 
									
										
										
										
											2019-07-29 16:13:48 +00:00
										 |  |  |             self._redirect_headers(originPathStr,cookie) | 
					
						
							|  |  |  |             self.server.POSTbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-02 14:36:03 +00:00
										 |  |  |         # decision to unblock in the web interface is confirmed | 
					
						
							|  |  |  |         if authorized and self.path.endswith('/unblockconfirm'): | 
					
						
							|  |  |  |             originPathStr=self.path.split('/unblockconfirm')[0] | 
					
						
							|  |  |  |             blockerNickname=getNicknameFromActor(originPathStr) | 
					
						
							|  |  |  |             length = int(self.headers['Content-length']) | 
					
						
							|  |  |  |             blockConfirmParams=self.rfile.read(length).decode('utf-8') | 
					
						
							|  |  |  |             if '&submitYes=' in blockConfirmParams: | 
					
						
							|  |  |  |                 blockingActor=blockConfirmParams.replace('%3A',':').replace('%2F','/').split('actor=')[1] | 
					
						
							|  |  |  |                 if '&' in blockingActor: | 
					
						
							|  |  |  |                     blockingActor=blockingActor.split('&')[0] | 
					
						
							|  |  |  |                 blockingNickname=getNicknameFromActor(blockingActor) | 
					
						
							|  |  |  |                 blockingDomain,blockingPort=getDomainFromActor(blockingActor) | 
					
						
							|  |  |  |                 blockingDomainFull=blockingDomain | 
					
						
							|  |  |  |                 if blockingPort: | 
					
						
							|  |  |  |                     if blockingPort!=80 and blockingPort!=443: | 
					
						
							| 
									
										
										
										
											2019-08-16 20:35:11 +00:00
										 |  |  |                         if ':' not in blockingDomain: | 
					
						
							|  |  |  |                             blockingDomainFull=blockingDomain+':'+str(blockingPort) | 
					
						
							| 
									
										
										
										
											2019-08-02 14:36:03 +00:00
										 |  |  |                 if blockerNickname==blockingNickname and \ | 
					
						
							|  |  |  |                    blockingDomain==self.server.domain and \ | 
					
						
							|  |  |  |                    blockingPort==self.server.port: | 
					
						
							|  |  |  |                     if self.server.debug: | 
					
						
							|  |  |  |                         print('You cannot unblock yourself!') | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     if self.server.debug: | 
					
						
							|  |  |  |                         print(blockerNickname+' stops blocking '+blockingActor) | 
					
						
							|  |  |  |                     removeBlock(self.server.baseDir,blockerNickname,self.server.domain, \ | 
					
						
							|  |  |  |                                 blockingNickname,blockingDomainFull) | 
					
						
							|  |  |  |             self._redirect_headers(originPathStr,cookie) | 
					
						
							|  |  |  |             self.server.POSTbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # decision to block in the web interface is confirmed | 
					
						
							|  |  |  |         if authorized and self.path.endswith('/blockconfirm'): | 
					
						
							|  |  |  |             originPathStr=self.path.split('/blockconfirm')[0] | 
					
						
							|  |  |  |             blockerNickname=getNicknameFromActor(originPathStr) | 
					
						
							|  |  |  |             length = int(self.headers['Content-length']) | 
					
						
							|  |  |  |             blockConfirmParams=self.rfile.read(length).decode('utf-8') | 
					
						
							|  |  |  |             if '&submitYes=' in blockConfirmParams: | 
					
						
							|  |  |  |                 blockingActor=blockConfirmParams.replace('%3A',':').replace('%2F','/').split('actor=')[1] | 
					
						
							|  |  |  |                 if '&' in blockingActor: | 
					
						
							|  |  |  |                     blockingActor=blockingActor.split('&')[0] | 
					
						
							|  |  |  |                 blockingNickname=getNicknameFromActor(blockingActor) | 
					
						
							|  |  |  |                 blockingDomain,blockingPort=getDomainFromActor(blockingActor) | 
					
						
							|  |  |  |                 blockingDomainFull=blockingDomain | 
					
						
							|  |  |  |                 if blockingPort: | 
					
						
							|  |  |  |                     if blockingPort!=80 and blockingPort!=443: | 
					
						
							| 
									
										
										
										
											2019-08-16 20:35:11 +00:00
										 |  |  |                         if ':' not in blockingDomain: | 
					
						
							|  |  |  |                             blockingDomainFull=blockingDomain+':'+str(blockingPort) | 
					
						
							| 
									
										
										
										
											2019-08-02 14:36:03 +00:00
										 |  |  |                 if blockerNickname==blockingNickname and \ | 
					
						
							|  |  |  |                    blockingDomain==self.server.domain and \ | 
					
						
							|  |  |  |                    blockingPort==self.server.port: | 
					
						
							|  |  |  |                     if self.server.debug: | 
					
						
							|  |  |  |                         print('You cannot block yourself!') | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     if self.server.debug: | 
					
						
							|  |  |  |                         print('Adding block by '+blockerNickname+' of '+blockingActor) | 
					
						
							|  |  |  |                     addBlock(self.server.baseDir,blockerNickname,self.server.domain, \ | 
					
						
							|  |  |  |                              blockingNickname,blockingDomainFull) | 
					
						
							|  |  |  |             self._redirect_headers(originPathStr,cookie) | 
					
						
							|  |  |  |             self.server.POSTbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-08-24 23:00:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # an option was chosen from person options screen | 
					
						
							|  |  |  |         # view/follow/block/report | 
					
						
							|  |  |  |         if authorized and self.path.endswith('/personoptions'): | 
					
						
							|  |  |  |             originPathStr=self.path.split('/personoptions')[0] | 
					
						
							|  |  |  |             chooserNickname=getNicknameFromActor(originPathStr) | 
					
						
							|  |  |  |             length = int(self.headers['Content-length']) | 
					
						
							|  |  |  |             optionsConfirmParams=self.rfile.read(length).decode('utf-8').replace('%3A',':').replace('%2F','/') | 
					
						
							| 
									
										
										
										
											2019-08-25 09:41:57 +00:00
										 |  |  |             # actor for the person | 
					
						
							| 
									
										
										
										
											2019-08-24 23:00:03 +00:00
										 |  |  |             optionsActor=optionsConfirmParams.split('actor=')[1] | 
					
						
							|  |  |  |             if '&' in optionsActor: | 
					
						
							|  |  |  |                 optionsActor=optionsActor.split('&')[0] | 
					
						
							| 
									
										
										
										
											2019-08-25 09:41:57 +00:00
										 |  |  |             # url of the avatar | 
					
						
							|  |  |  |             optionsAvatarUrl=optionsConfirmParams.split('avatarUrl=')[1] | 
					
						
							|  |  |  |             if '&' in optionsAvatarUrl: | 
					
						
							|  |  |  |                 optionsAvatarUrl=optionsAvatarUrl.split('&')[0] | 
					
						
							|  |  |  |             # link to a post, which can then be included in reports | 
					
						
							|  |  |  |             postUrl=None | 
					
						
							|  |  |  |             if 'postUrl' in optionsConfirmParams: | 
					
						
							|  |  |  |                 postUrl=optionsConfirmParams.split('postUrl=')[1] | 
					
						
							|  |  |  |                 if '&' in postUrl: | 
					
						
							|  |  |  |                     postUrl=postUrl.split('&')[0] | 
					
						
							|  |  |  |                  | 
					
						
							| 
									
										
										
										
											2019-08-24 23:00:03 +00:00
										 |  |  |             optionsNickname=getNicknameFromActor(optionsActor) | 
					
						
							|  |  |  |             optionsDomain,optionsPort=getDomainFromActor(optionsActor) | 
					
						
							|  |  |  |             optionsDomainFull=optionsDomain | 
					
						
							|  |  |  |             if optionsPort: | 
					
						
							|  |  |  |                 if optionsPort!=80 and optionsPort!=443: | 
					
						
							|  |  |  |                     if ':' not in optionsDomain: | 
					
						
							|  |  |  |                         optionsDomainFull=optionsDomain+':'+str(optionsPort) | 
					
						
							|  |  |  |             if chooserNickname==optionsNickname and \ | 
					
						
							|  |  |  |                optionsDomain==self.server.domain and \ | 
					
						
							|  |  |  |                optionsPort==self.server.port: | 
					
						
							|  |  |  |                 if self.server.debug: | 
					
						
							|  |  |  |                     print('You cannot perform an option action on yourself') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if '&submitView=' in optionsConfirmParams: | 
					
						
							|  |  |  |                 if self.server.debug: | 
					
						
							|  |  |  |                     print('Viewing '+optionsActor) | 
					
						
							|  |  |  |                 self._redirect_headers(optionsActor,cookie) | 
					
						
							|  |  |  |                 self.server.POSTbusy=False | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  |             if '&submitBlock=' in optionsConfirmParams: | 
					
						
							|  |  |  |                 if self.server.debug: | 
					
						
							|  |  |  |                     print('Adding block by '+chooserNickname+' of '+optionsActor) | 
					
						
							|  |  |  |                 addBlock(self.server.baseDir,chooserNickname,self.server.domain, \ | 
					
						
							|  |  |  |                          optionsNickname,optionsDomainFull) | 
					
						
							|  |  |  |             if '&submitUnblock=' in optionsConfirmParams: | 
					
						
							|  |  |  |                 if self.server.debug: | 
					
						
							|  |  |  |                     print('Unblocking '+optionsActor) | 
					
						
							|  |  |  |                 msg=htmlUnblockConfirm(self.server.baseDir,originPathStr,optionsActor,optionsAvatarUrl).encode() | 
					
						
							|  |  |  |                 self._set_headers('text/html',len(msg),cookie) | 
					
						
							|  |  |  |                 self.wfile.write(msg) | 
					
						
							|  |  |  |                 self.server.POSTbusy=False | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  |             if '&submitFollow=' in optionsConfirmParams: | 
					
						
							|  |  |  |                 if self.server.debug: | 
					
						
							|  |  |  |                     print('Following '+optionsActor) | 
					
						
							|  |  |  |                 msg=htmlFollowConfirm(self.server.baseDir,originPathStr,optionsActor,optionsAvatarUrl).encode() | 
					
						
							|  |  |  |                 self._set_headers('text/html',len(msg),cookie) | 
					
						
							|  |  |  |                 self.wfile.write(msg) | 
					
						
							|  |  |  |                 self.server.POSTbusy=False | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  |             if '&submitUnfollow=' in optionsConfirmParams: | 
					
						
							|  |  |  |                 if self.server.debug: | 
					
						
							|  |  |  |                     print('Unfollowing '+optionsActor) | 
					
						
							|  |  |  |                 msg=htmlUnfollowConfirm(self.server.baseDir,originPathStr,optionsActor,optionsAvatarUrl).encode() | 
					
						
							|  |  |  |                 self._set_headers('text/html',len(msg),cookie) | 
					
						
							|  |  |  |                 self.wfile.write(msg) | 
					
						
							|  |  |  |                 self.server.POSTbusy=False | 
					
						
							|  |  |  |                 return | 
					
						
							| 
									
										
										
										
											2019-08-25 10:30:39 +00:00
										 |  |  |             if '&submitDM=' in optionsConfirmParams: | 
					
						
							|  |  |  |                 if self.server.debug: | 
					
						
							|  |  |  |                     print('Sending DM to '+optionsActor) | 
					
						
							|  |  |  |                 reportPath=self.path.replace('/personoptions','')+'/newdm' | 
					
						
							| 
									
										
										
										
											2019-08-25 10:32:28 +00:00
										 |  |  |                 msg=htmlNewPost(self.server.baseDir,reportPath,None,[optionsActor],None).encode() | 
					
						
							| 
									
										
										
										
											2019-08-25 10:30:39 +00:00
										 |  |  |                 self._set_headers('text/html',len(msg),cookie) | 
					
						
							|  |  |  |                 self.wfile.write(msg) | 
					
						
							|  |  |  |                 self.server.POSTbusy=False | 
					
						
							|  |  |  |                 return             | 
					
						
							| 
									
										
										
										
											2019-08-24 23:00:03 +00:00
										 |  |  |             if '&submitReport=' in optionsConfirmParams: | 
					
						
							|  |  |  |                 if self.server.debug: | 
					
						
							|  |  |  |                     print('Reporting '+optionsActor) | 
					
						
							| 
									
										
										
										
											2019-08-25 09:49:27 +00:00
										 |  |  |                 reportPath=self.path.replace('/personoptions','')+'/newreport' | 
					
						
							|  |  |  |                 msg=htmlNewPost(self.server.baseDir,reportPath,None,[],postUrl).encode() | 
					
						
							| 
									
										
										
										
											2019-08-24 23:00:03 +00:00
										 |  |  |                 self._set_headers('text/html',len(msg),cookie) | 
					
						
							|  |  |  |                 self.wfile.write(msg) | 
					
						
							|  |  |  |                 self.server.POSTbusy=False | 
					
						
							|  |  |  |                 return             | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             self._redirect_headers(originPathStr,cookie) | 
					
						
							|  |  |  |             self.server.POSTbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-08-02 14:36:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-28 15:16:14 +00:00
										 |  |  |         postState=self._receiveNewPost(authorized,'newpost') | 
					
						
							|  |  |  |         if postState!=0: | 
					
						
							|  |  |  |             nickname=self.path.split('/users/')[1] | 
					
						
							|  |  |  |             if '/' in nickname: | 
					
						
							|  |  |  |                 nickname=nickname.split('/')[0] | 
					
						
							| 
									
										
										
										
											2019-08-25 10:21:27 +00:00
										 |  |  |             self._redirect_headers('/users/'+nickname+'/inbox',cookie) | 
					
						
							| 
									
										
										
										
											2019-07-27 20:30:58 +00:00
										 |  |  |             self.server.POSTbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-07-28 15:16:14 +00:00
										 |  |  |         postState=self._receiveNewPost(authorized,'newunlisted') | 
					
						
							|  |  |  |         if postState!=0: | 
					
						
							|  |  |  |             nickname=self.path.split('/users/')[1] | 
					
						
							|  |  |  |             if '/' in nickname: | 
					
						
							|  |  |  |                 nickname=nickname.split('/')[0] | 
					
						
							| 
									
										
										
										
											2019-08-25 10:21:27 +00:00
										 |  |  |             self._redirect_headers('/users/'+nickname+'/inbox',cookie) | 
					
						
							| 
									
										
										
										
											2019-07-27 20:30:58 +00:00
										 |  |  |             self.server.POSTbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-07-28 15:16:14 +00:00
										 |  |  |         postState=self._receiveNewPost(authorized,'newfollowers') | 
					
						
							|  |  |  |         if postState!=0: | 
					
						
							| 
									
										
										
										
											2019-08-11 18:32:29 +00:00
										 |  |  |             nickname=self.path.split('/users/')[1] | 
					
						
							| 
									
										
										
										
											2019-07-28 15:16:14 +00:00
										 |  |  |             if '/' in nickname: | 
					
						
							|  |  |  |                 nickname=nickname.split('/')[0] | 
					
						
							| 
									
										
										
										
											2019-08-25 10:21:27 +00:00
										 |  |  |             self._redirect_headers('/users/'+nickname+'/inbox',cookie) | 
					
						
							| 
									
										
										
										
											2019-07-27 20:30:58 +00:00
										 |  |  |             self.server.POSTbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-07-28 15:16:14 +00:00
										 |  |  |         postState=self._receiveNewPost(authorized,'newdm') | 
					
						
							| 
									
										
										
										
											2019-08-11 11:25:27 +00:00
										 |  |  |         if postState!=0: | 
					
						
							| 
									
										
										
										
											2019-08-11 18:32:29 +00:00
										 |  |  |             nickname=self.path.split('/users/')[1] | 
					
						
							| 
									
										
										
										
											2019-08-11 11:25:27 +00:00
										 |  |  |             if '/' in nickname: | 
					
						
							|  |  |  |                 nickname=nickname.split('/')[0] | 
					
						
							| 
									
										
										
										
											2019-08-25 10:21:27 +00:00
										 |  |  |             self._redirect_headers('/users/'+nickname+'/inbox',cookie) | 
					
						
							| 
									
										
										
										
											2019-08-11 11:25:27 +00:00
										 |  |  |             self.server.POSTbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         postState=self._receiveNewPost(authorized,'newreport') | 
					
						
							| 
									
										
										
										
											2019-07-28 15:16:14 +00:00
										 |  |  |         if postState!=0: | 
					
						
							| 
									
										
										
										
											2019-08-11 18:32:29 +00:00
										 |  |  |             nickname=self.path.split('/users/')[1] | 
					
						
							| 
									
										
										
										
											2019-07-28 15:16:14 +00:00
										 |  |  |             if '/' in nickname: | 
					
						
							|  |  |  |                 nickname=nickname.split('/')[0] | 
					
						
							| 
									
										
										
										
											2019-08-25 10:21:27 +00:00
										 |  |  |             self._redirect_headers('/users/'+nickname+'/inbox',cookie) | 
					
						
							| 
									
										
										
										
											2019-07-27 20:30:58 +00:00
										 |  |  |             self.server.POSTbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-07-28 15:16:14 +00:00
										 |  |  |         postState=self._receiveNewPost(authorized,'newshare') | 
					
						
							|  |  |  |         if postState!=0: | 
					
						
							| 
									
										
										
										
											2019-08-11 18:32:29 +00:00
										 |  |  |             nickname=self.path.split('/users/')[1] | 
					
						
							| 
									
										
										
										
											2019-07-28 15:16:14 +00:00
										 |  |  |             if '/' in nickname: | 
					
						
							|  |  |  |                 nickname=nickname.split('/')[0] | 
					
						
							| 
									
										
										
										
											2019-08-25 10:08:47 +00:00
										 |  |  |             self._redirect_headers('/users/'+nickname+'/shares',cookie) | 
					
						
							| 
									
										
										
										
											2019-07-27 20:30:58 +00:00
										 |  |  |             self.server.POSTbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-07-29 16:13:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-23 19:02:26 +00:00
										 |  |  |         if self.path.endswith('/outbox') or self.path.endswith('/shares'): | 
					
						
							| 
									
										
										
										
											2019-07-03 20:03:38 +00:00
										 |  |  |             if '/users/' in self.path: | 
					
						
							| 
									
										
										
										
											2019-07-27 20:30:58 +00:00
										 |  |  |                 if authorized: | 
					
						
							| 
									
										
										
										
											2019-07-12 11:05:43 +00:00
										 |  |  |                     self.outboxAuthenticated=True | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |                     pathUsersSection=self.path.split('/users/')[1] | 
					
						
							| 
									
										
										
										
											2019-07-12 11:05:43 +00:00
										 |  |  |                     self.postToNickname=pathUsersSection.split('/')[0] | 
					
						
							| 
									
										
										
										
											2019-07-03 21:37:46 +00:00
										 |  |  |             if not self.outboxAuthenticated: | 
					
						
							|  |  |  |                 self.send_response(405) | 
					
						
							|  |  |  |                 self.end_headers() | 
					
						
							|  |  |  |                 self.server.POSTbusy=False | 
					
						
							|  |  |  |                 return | 
					
						
							| 
									
										
										
										
											2019-07-03 16:14:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # check that the post is to an expected path | 
					
						
							| 
									
										
										
										
											2019-07-05 10:21:10 +00:00
										 |  |  |         if not (self.path.endswith('/outbox') or \ | 
					
						
							|  |  |  |                 self.path.endswith('/inbox') or \ | 
					
						
							| 
									
										
										
										
											2019-07-23 19:02:26 +00:00
										 |  |  |                 self.path.endswith('/shares') or \ | 
					
						
							| 
									
										
										
										
											2019-08-13 10:59:38 +00:00
										 |  |  |                 self.path.endswith('/moderationaction') or \ | 
					
						
							| 
									
										
										
										
											2019-07-05 21:24:16 +00:00
										 |  |  |                 self.path.endswith('/caps/new') or \ | 
					
						
							| 
									
										
										
										
											2019-07-05 10:21:10 +00:00
										 |  |  |                 self.path=='/sharedInbox'): | 
					
						
							| 
									
										
										
										
											2019-07-03 16:14:45 +00:00
										 |  |  |             print('Attempt to POST to invalid path '+self.path) | 
					
						
							|  |  |  |             self.send_response(400) | 
					
						
							|  |  |  |             self.end_headers() | 
					
						
							|  |  |  |             self.server.POSTbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |         # read the message and convert it into a python dictionary | 
					
						
							| 
									
										
										
										
											2019-07-01 11:48:54 +00:00
										 |  |  |         length = int(self.headers['Content-length']) | 
					
						
							| 
									
										
										
										
											2019-07-03 16:14:45 +00:00
										 |  |  |         if self.server.debug: | 
					
						
							|  |  |  |             print('DEBUG: content-length: '+str(length)) | 
					
						
							| 
									
										
										
										
											2019-07-16 14:23:06 +00:00
										 |  |  |         if not self.headers['Content-type'].startswith('image/'): | 
					
						
							|  |  |  |             if length>self.server.maxMessageLength: | 
					
						
							| 
									
										
										
										
											2019-07-19 15:22:04 +00:00
										 |  |  |                 print('Maximum message length exceeded '+str(length)) | 
					
						
							| 
									
										
										
										
											2019-07-16 14:23:06 +00:00
										 |  |  |                 self.send_response(400) | 
					
						
							|  |  |  |                 self.end_headers() | 
					
						
							|  |  |  |                 self.server.POSTbusy=False | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             if length>self.server.maxImageSize: | 
					
						
							| 
									
										
										
										
											2019-07-19 15:22:04 +00:00
										 |  |  |                 print('Maximum image size exceeded '+str(length)) | 
					
						
							| 
									
										
										
										
											2019-07-16 14:23:06 +00:00
										 |  |  |                 self.send_response(400) | 
					
						
							|  |  |  |                 self.end_headers() | 
					
						
							|  |  |  |                 self.server.POSTbusy=False | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # receive images to the outbox | 
					
						
							|  |  |  |         if self.headers['Content-type'].startswith('image/') and \ | 
					
						
							|  |  |  |            '/users/' in self.path: | 
					
						
							|  |  |  |             if not self.outboxAuthenticated: | 
					
						
							|  |  |  |                 if self.server.debug: | 
					
						
							| 
									
										
										
										
											2019-08-16 18:32:26 +00:00
										 |  |  |                     print('DEBUG: unauthenticated attempt to post image to outbox') | 
					
						
							| 
									
										
										
										
											2019-07-16 14:23:06 +00:00
										 |  |  |                 self.send_response(403) | 
					
						
							|  |  |  |                 self.end_headers() | 
					
						
							|  |  |  |                 self.server.POSTbusy=False | 
					
						
							|  |  |  |                 return             | 
					
						
							|  |  |  |             pathUsersSection=self.path.split('/users/')[1] | 
					
						
							|  |  |  |             if '/' not in pathUsersSection: | 
					
						
							|  |  |  |                 self.send_response(404) | 
					
						
							|  |  |  |                 self.end_headers() | 
					
						
							|  |  |  |                 self.server.POSTbusy=False | 
					
						
							|  |  |  |                 return                 | 
					
						
							|  |  |  |             self.postFromNickname=pathUsersSection.split('/')[0] | 
					
						
							|  |  |  |             accountsDir=self.server.baseDir+'/accounts/'+self.postFromNickname+'@'+self.server.domain | 
					
						
							|  |  |  |             if not os.path.isdir(accountsDir): | 
					
						
							|  |  |  |                 self.send_response(404) | 
					
						
							|  |  |  |                 self.end_headers() | 
					
						
							|  |  |  |                 self.server.POSTbusy=False | 
					
						
							|  |  |  |                 return                 | 
					
						
							|  |  |  |             mediaBytes=self.rfile.read(length) | 
					
						
							|  |  |  |             mediaFilenameBase=accountsDir+'/upload' | 
					
						
							|  |  |  |             mediaFilename=mediaFilenameBase+'.png' | 
					
						
							|  |  |  |             if self.headers['Content-type'].endswith('jpeg'): | 
					
						
							|  |  |  |                 mediaFilename=mediaFilenameBase+'.jpg' | 
					
						
							|  |  |  |             if self.headers['Content-type'].endswith('gif'): | 
					
						
							|  |  |  |                 mediaFilename=mediaFilenameBase+'.gif' | 
					
						
							|  |  |  |             with open(mediaFilename, 'wb') as avFile: | 
					
						
							|  |  |  |                 avFile.write(mediaBytes) | 
					
						
							|  |  |  |             if self.server.debug: | 
					
						
							|  |  |  |                 print('DEBUG: image saved to '+mediaFilename) | 
					
						
							|  |  |  |             self.send_response(201) | 
					
						
							|  |  |  |             self.end_headers() | 
					
						
							|  |  |  |             self.server.POSTbusy=False | 
					
						
							|  |  |  |             return             | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # refuse to receive non-json content | 
					
						
							| 
									
										
										
										
											2019-08-14 23:04:41 +00:00
										 |  |  |         if self.headers['Content-type'] != 'application/json' and \ | 
					
						
							|  |  |  |            self.headers['Content-type'] != 'application/activity+json': | 
					
						
							| 
									
										
										
										
											2019-07-16 14:23:06 +00:00
										 |  |  |             print("POST is not json: "+self.headers['Content-type']) | 
					
						
							| 
									
										
										
										
											2019-08-14 22:33:55 +00:00
										 |  |  |             if self.server.debug: | 
					
						
							|  |  |  |                 print(str(self.headers)) | 
					
						
							|  |  |  |                 length = int(self.headers['Content-length']) | 
					
						
							|  |  |  |                 if length<self.server.maxPostLength: | 
					
						
							|  |  |  |                     unknownPost=self.rfile.read(length).decode('utf-8') | 
					
						
							|  |  |  |                     print(str(unknownPost)) | 
					
						
							| 
									
										
										
										
											2019-06-28 21:06:05 +00:00
										 |  |  |             self.send_response(400) | 
					
						
							|  |  |  |             self.end_headers() | 
					
						
							| 
									
										
										
										
											2019-07-01 14:30:48 +00:00
										 |  |  |             self.server.POSTbusy=False | 
					
						
							| 
									
										
										
										
											2019-06-28 21:06:05 +00:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-07-03 16:14:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if self.server.debug: | 
					
						
							|  |  |  |             print('DEBUG: Reading message') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-01 11:48:54 +00:00
										 |  |  |         messageBytes=self.rfile.read(length) | 
					
						
							| 
									
										
										
										
											2019-07-16 14:23:06 +00:00
										 |  |  |         messageJson=json.loads(messageBytes) | 
					
						
							| 
									
										
										
										
											2019-07-18 11:35:48 +00:00
										 |  |  |              | 
					
						
							| 
									
										
										
										
											2019-07-03 21:37:46 +00:00
										 |  |  |         # https://www.w3.org/TR/activitypub/#object-without-create | 
					
						
							|  |  |  |         if self.outboxAuthenticated: | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |             if self._postToOutbox(messageJson):                 | 
					
						
							| 
									
										
										
										
											2019-07-16 19:07:45 +00:00
										 |  |  |                 if messageJson.get('id'): | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |                     self.headers['Location']= \ | 
					
						
							| 
									
										
										
										
											2019-08-16 19:48:32 +00:00
										 |  |  |                         messageJson['id'].replace('/activity','').replace('/undo','') | 
					
						
							| 
									
										
										
										
											2019-07-03 22:16:03 +00:00
										 |  |  |                 self.send_response(201) | 
					
						
							|  |  |  |                 self.end_headers() | 
					
						
							|  |  |  |                 self.server.POSTbusy=False | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  |             else: | 
					
						
							| 
									
										
										
										
											2019-08-16 18:32:26 +00:00
										 |  |  |                 if self.server.debug: | 
					
						
							|  |  |  |                     print('Failed to post to outbox') | 
					
						
							| 
									
										
										
										
											2019-07-03 22:16:03 +00:00
										 |  |  |                 self.send_response(403) | 
					
						
							|  |  |  |                 self.end_headers() | 
					
						
							|  |  |  |                 self.server.POSTbusy=False | 
					
						
							|  |  |  |                 return | 
					
						
							| 
									
										
										
										
											2019-07-03 21:37:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-02 15:07:27 +00:00
										 |  |  |         # check the necessary properties are available | 
					
						
							| 
									
										
										
										
											2019-07-03 16:14:45 +00:00
										 |  |  |         if self.server.debug: | 
					
						
							|  |  |  |             print('DEBUG: Check message has params') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-05 15:10:21 +00:00
										 |  |  |         if self.path.endswith('/inbox') or \ | 
					
						
							|  |  |  |            self.path=='/sharedInbox': | 
					
						
							| 
									
										
										
										
											2019-07-03 21:37:46 +00:00
										 |  |  |             if not inboxMessageHasParams(messageJson): | 
					
						
							| 
									
										
										
										
											2019-07-06 13:49:25 +00:00
										 |  |  |                 if self.server.debug: | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |                     pprint(messageJson) | 
					
						
							| 
									
										
										
										
											2019-07-06 13:49:25 +00:00
										 |  |  |                     print("DEBUG: inbox message doesn't have the required parameters") | 
					
						
							| 
									
										
										
										
											2019-07-03 21:37:46 +00:00
										 |  |  |                 self.send_response(403) | 
					
						
							|  |  |  |                 self.end_headers() | 
					
						
							|  |  |  |                 self.server.POSTbusy=False | 
					
						
							|  |  |  |                 return | 
					
						
							| 
									
										
										
										
											2019-07-02 15:07:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-06 17:00:22 +00:00
										 |  |  |         if not inboxPermittedMessage(self.server.domain, \ | 
					
						
							|  |  |  |                                      messageJson, \ | 
					
						
							| 
									
										
										
										
											2019-07-09 14:20:23 +00:00
										 |  |  |                                      self.server.federationList): | 
					
						
							| 
									
										
										
										
											2019-07-03 16:14:45 +00:00
										 |  |  |             if self.server.debug: | 
					
						
							| 
									
										
										
										
											2019-07-05 13:26:54 +00:00
										 |  |  |                 # https://www.youtube.com/watch?v=K3PrSj9XEu4 | 
					
						
							| 
									
										
										
										
											2019-07-03 16:14:45 +00:00
										 |  |  |                 print('DEBUG: Ah Ah Ah') | 
					
						
							| 
									
										
										
										
											2019-06-28 21:59:54 +00:00
										 |  |  |             self.send_response(403) | 
					
						
							|  |  |  |             self.end_headers() | 
					
						
							| 
									
										
										
										
											2019-07-01 14:30:48 +00:00
										 |  |  |             self.server.POSTbusy=False | 
					
						
							| 
									
										
										
										
											2019-07-01 11:48:54 +00:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-07-01 14:30:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-05 10:21:10 +00:00
										 |  |  |         if self.server.debug: | 
					
						
							|  |  |  |             pprint(messageJson) | 
					
						
							| 
									
										
										
										
											2019-07-02 17:11:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-04 14:36:29 +00:00
										 |  |  |         if not self.headers.get('signature'): | 
					
						
							|  |  |  |             if 'keyId=' not in self.headers['signature']: | 
					
						
							|  |  |  |                 if self.server.debug: | 
					
						
							|  |  |  |                     print('DEBUG: POST to inbox has no keyId in header signature parameter') | 
					
						
							| 
									
										
										
										
											2019-08-16 18:32:26 +00:00
										 |  |  |                 self.send_response(403) | 
					
						
							|  |  |  |                 self.end_headers() | 
					
						
							|  |  |  |                 self.server.POSTbusy=False | 
					
						
							|  |  |  |                 return | 
					
						
							| 
									
										
										
										
											2019-07-04 10:02:56 +00:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2019-07-03 16:14:45 +00:00
										 |  |  |         if self.server.debug: | 
					
						
							| 
									
										
										
										
											2019-07-06 13:49:25 +00:00
										 |  |  |             print('DEBUG: POST saving to inbox queue') | 
					
						
							| 
									
										
										
										
											2019-07-04 10:02:56 +00:00
										 |  |  |         if '/users/' in self.path: | 
					
						
							|  |  |  |             pathUsersSection=self.path.split('/users/')[1] | 
					
						
							|  |  |  |             if '/' not in pathUsersSection: | 
					
						
							|  |  |  |                 if self.server.debug: | 
					
						
							|  |  |  |                     print('DEBUG: This is not a users endpoint') | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 self.postToNickname=pathUsersSection.split('/')[0] | 
					
						
							|  |  |  |                 if self.postToNickname: | 
					
						
							| 
									
										
										
										
											2019-08-16 17:19:23 +00:00
										 |  |  |                     queueStatus=self._updateInboxQueue(self.postToNickname,messageJson,messageBytes) | 
					
						
							| 
									
										
										
										
											2019-07-15 12:27:26 +00:00
										 |  |  |                     if queueStatus==0: | 
					
						
							|  |  |  |                         self.send_response(200) | 
					
						
							|  |  |  |                         self.end_headers() | 
					
						
							|  |  |  |                         self.server.POSTbusy=False | 
					
						
							| 
									
										
										
										
											2019-07-04 12:23:53 +00:00
										 |  |  |                         return | 
					
						
							| 
									
										
										
										
											2019-07-15 12:27:26 +00:00
										 |  |  |                     if queueStatus==1: | 
					
						
							| 
									
										
										
										
											2019-07-15 12:28:41 +00:00
										 |  |  |                         self.send_response(503) | 
					
						
							| 
									
										
										
										
											2019-07-15 12:27:26 +00:00
										 |  |  |                         self.end_headers() | 
					
						
							|  |  |  |                         self.server.POSTbusy=False | 
					
						
							| 
									
										
										
										
											2019-08-14 23:04:41 +00:00
										 |  |  |                         return | 
					
						
							| 
									
										
										
										
											2019-08-16 18:32:26 +00:00
										 |  |  |                     if self.server.debug: | 
					
						
							| 
									
										
										
										
											2019-08-16 19:13:58 +00:00
										 |  |  |                         print('_updateInboxQueue exited without doing anything') | 
					
						
							| 
									
										
										
										
											2019-08-14 23:04:41 +00:00
										 |  |  |                 else: | 
					
						
							|  |  |  |                     if self.server.debug: | 
					
						
							|  |  |  |                         print('self.postToNickname is None') | 
					
						
							| 
									
										
										
										
											2019-07-04 12:23:53 +00:00
										 |  |  |             self.send_response(403) | 
					
						
							| 
									
										
										
										
											2019-07-01 14:30:48 +00:00
										 |  |  |             self.end_headers() | 
					
						
							|  |  |  |             self.server.POSTbusy=False | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-07-04 12:23:53 +00:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2019-07-05 15:10:21 +00:00
										 |  |  |             if self.path == '/sharedInbox' or self.path == '/inbox': | 
					
						
							| 
									
										
										
										
											2019-07-05 10:24:20 +00:00
										 |  |  |                 print('DEBUG: POST to shared inbox') | 
					
						
							| 
									
										
										
										
											2019-08-16 17:19:23 +00:00
										 |  |  |                 queueStatus=self._updateInboxQueue('inbox',messageJson,messageBytes) | 
					
						
							| 
									
										
										
										
											2019-07-15 12:27:26 +00:00
										 |  |  |                 if queueStatus==0: | 
					
						
							|  |  |  |                     self.send_response(200) | 
					
						
							|  |  |  |                     self.end_headers() | 
					
						
							|  |  |  |                     self.server.POSTbusy=False | 
					
						
							| 
									
										
										
										
											2019-07-05 11:27:18 +00:00
										 |  |  |                     return | 
					
						
							| 
									
										
										
										
											2019-07-15 12:27:26 +00:00
										 |  |  |                 if queueStatus==1: | 
					
						
							| 
									
										
										
										
											2019-07-15 12:28:41 +00:00
										 |  |  |                     self.send_response(503) | 
					
						
							| 
									
										
										
										
											2019-07-15 12:27:26 +00:00
										 |  |  |                     self.end_headers() | 
					
						
							|  |  |  |                     self.server.POSTbusy=False | 
					
						
							|  |  |  |                     return                     | 
					
						
							| 
									
										
										
										
											2019-07-05 10:24:20 +00:00
										 |  |  |         self.send_response(200) | 
					
						
							|  |  |  |         self.end_headers() | 
					
						
							|  |  |  |         self.server.POSTbusy=False | 
					
						
							| 
									
										
										
										
											2019-07-03 16:14:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-17 15:16:27 +00:00
										 |  |  | class PubServerUnitTest(PubServer): | 
					
						
							|  |  |  |     protocol_version = 'HTTP/1.0' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-14 20:12:27 +00:00
										 |  |  | def runDaemon(projectVersion, \ | 
					
						
							|  |  |  |               instanceId,clientToServer: bool, \ | 
					
						
							| 
									
										
										
										
											2019-08-02 12:49:34 +00:00
										 |  |  |               baseDir: str,domain: str, \ | 
					
						
							| 
									
										
										
										
											2019-08-14 13:52:19 +00:00
										 |  |  |               port=80,proxyPort=80,httpPrefix='https', \ | 
					
						
							| 
									
										
										
										
											2019-07-09 18:11:23 +00:00
										 |  |  |               fedList=[],noreply=False,nolike=False,nopics=False, \ | 
					
						
							|  |  |  |               noannounce=False,cw=False,ocapAlways=False, \ | 
					
						
							| 
									
										
										
										
											2019-07-15 10:22:19 +00:00
										 |  |  |               useTor=False,maxReplies=64, \ | 
					
						
							| 
									
										
										
										
											2019-07-15 10:27:53 +00:00
										 |  |  |               domainMaxPostsPerDay=8640,accountMaxPostsPerDay=8640, \ | 
					
						
							| 
									
										
										
										
											2019-08-28 09:59:19 +00:00
										 |  |  |               allowDeletion=False,debug=False,unitTest=False, \ | 
					
						
							|  |  |  |               instanceOnlySkillsSearch=False) -> None: | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |     if len(domain)==0: | 
					
						
							| 
									
										
										
										
											2019-07-03 09:24:55 +00:00
										 |  |  |         domain='localhost' | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |     if '.' not in domain: | 
					
						
							| 
									
										
										
										
											2019-07-03 12:24:54 +00:00
										 |  |  |         if domain != 'localhost': | 
					
						
							|  |  |  |             print('Invalid domain: ' + domain) | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-14 13:52:19 +00:00
										 |  |  |     serverAddress = ('', proxyPort) | 
					
						
							| 
									
										
										
										
											2019-08-17 15:16:27 +00:00
										 |  |  |     if unitTest:  | 
					
						
							|  |  |  |         httpd = ThreadingHTTPServer(serverAddress, PubServerUnitTest) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         httpd = ThreadingHTTPServer(serverAddress, PubServer) | 
					
						
							| 
									
										
										
										
											2019-07-27 20:30:58 +00:00
										 |  |  |     # max POST size of 10M | 
					
						
							| 
									
										
										
										
											2019-08-14 20:12:27 +00:00
										 |  |  |     httpd.projectVersion=projectVersion | 
					
						
							| 
									
										
										
										
											2019-07-27 20:30:58 +00:00
										 |  |  |     httpd.maxPostLength=1024*1024*10 | 
					
						
							| 
									
										
										
										
											2019-08-20 11:51:29 +00:00
										 |  |  |     httpd.maxPostsInBox=256 | 
					
						
							| 
									
										
										
										
											2019-06-30 20:03:23 +00:00
										 |  |  |     httpd.domain=domain | 
					
						
							|  |  |  |     httpd.port=port | 
					
						
							| 
									
										
										
										
											2019-07-25 09:13:02 +00:00
										 |  |  |     httpd.domainFull=domain | 
					
						
							| 
									
										
										
										
											2019-08-16 20:35:11 +00:00
										 |  |  |     if port: | 
					
						
							|  |  |  |         if port!=80 and port!=443: | 
					
						
							|  |  |  |             if ':' not in domain: | 
					
						
							|  |  |  |                 httpd.domainFull=domain+':'+str(port) | 
					
						
							| 
									
										
										
										
											2019-07-03 19:00:03 +00:00
										 |  |  |     httpd.httpPrefix=httpPrefix | 
					
						
							| 
									
										
										
										
											2019-07-03 16:14:45 +00:00
										 |  |  |     httpd.debug=debug | 
					
						
							| 
									
										
										
										
											2019-06-30 20:03:23 +00:00
										 |  |  |     httpd.federationList=fedList.copy() | 
					
						
							| 
									
										
										
										
											2019-07-04 20:25:19 +00:00
										 |  |  |     httpd.baseDir=baseDir | 
					
						
							| 
									
										
										
										
											2019-08-02 12:49:34 +00:00
										 |  |  |     httpd.instanceId=instanceId | 
					
						
							| 
									
										
										
										
											2019-07-01 14:30:48 +00:00
										 |  |  |     httpd.personCache={} | 
					
						
							|  |  |  |     httpd.cachedWebfingers={} | 
					
						
							|  |  |  |     httpd.useTor=useTor | 
					
						
							| 
									
										
										
										
											2019-07-02 17:11:59 +00:00
										 |  |  |     httpd.session = None | 
					
						
							|  |  |  |     httpd.sessionLastUpdate=0 | 
					
						
							| 
									
										
										
										
											2019-07-01 14:30:48 +00:00
										 |  |  |     httpd.lastGET=0 | 
					
						
							|  |  |  |     httpd.lastPOST=0 | 
					
						
							|  |  |  |     httpd.GETbusy=False | 
					
						
							|  |  |  |     httpd.POSTbusy=False | 
					
						
							| 
									
										
										
										
											2019-07-01 21:01:43 +00:00
										 |  |  |     httpd.receivedMessage=False | 
					
						
							| 
									
										
										
										
											2019-07-04 10:02:56 +00:00
										 |  |  |     httpd.inboxQueue=[] | 
					
						
							| 
									
										
										
										
											2019-07-05 18:57:19 +00:00
										 |  |  |     httpd.sendThreads=[] | 
					
						
							|  |  |  |     httpd.postLog=[] | 
					
						
							| 
									
										
										
										
											2019-07-15 12:27:26 +00:00
										 |  |  |     httpd.maxQueueLength=16 | 
					
						
							| 
									
										
										
										
											2019-07-07 17:47:37 +00:00
										 |  |  |     httpd.ocapAlways=ocapAlways | 
					
						
							| 
									
										
										
										
											2019-07-16 14:23:06 +00:00
										 |  |  |     httpd.maxMessageLength=5000 | 
					
						
							|  |  |  |     httpd.maxImageSize=10*1024*1024 | 
					
						
							| 
									
										
										
										
											2019-07-17 19:31:52 +00:00
										 |  |  |     httpd.allowDeletion=allowDeletion | 
					
						
							| 
									
										
										
										
											2019-07-24 22:38:42 +00:00
										 |  |  |     httpd.lastLoginTime=0 | 
					
						
							| 
									
										
										
										
											2019-08-02 18:04:31 +00:00
										 |  |  |     httpd.maxReplies=maxReplies | 
					
						
							| 
									
										
										
										
											2019-07-25 14:24:42 +00:00
										 |  |  |     httpd.salts={} | 
					
						
							|  |  |  |     httpd.tokens={} | 
					
						
							|  |  |  |     httpd.tokensLookup={} | 
					
						
							| 
									
										
										
										
											2019-08-28 09:59:19 +00:00
										 |  |  |     httpd.instanceOnlySkillsSearch=instanceOnlySkillsSearch | 
					
						
							| 
									
										
										
										
											2019-07-09 17:54:08 +00:00
										 |  |  |     httpd.acceptedCaps=["inbox:write","objects:read"] | 
					
						
							|  |  |  |     if noreply: | 
					
						
							|  |  |  |         httpd.acceptedCaps.append('inbox:noreply') | 
					
						
							|  |  |  |     if nolike: | 
					
						
							|  |  |  |         httpd.acceptedCaps.append('inbox:nolike') | 
					
						
							| 
									
										
										
										
											2019-07-09 18:11:23 +00:00
										 |  |  |     if nopics: | 
					
						
							|  |  |  |         httpd.acceptedCaps.append('inbox:nopics') | 
					
						
							|  |  |  |     if noannounce: | 
					
						
							|  |  |  |         httpd.acceptedCaps.append('inbox:noannounce') | 
					
						
							|  |  |  |     if cw: | 
					
						
							|  |  |  |         httpd.acceptedCaps.append('inbox:cw') | 
					
						
							| 
									
										
										
										
											2019-07-11 12:29:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-18 13:10:26 +00:00
										 |  |  |     if not os.path.isdir(baseDir+'/accounts/inbox@'+domain): | 
					
						
							|  |  |  |         print('Creating shared inbox: inbox@'+domain) | 
					
						
							|  |  |  |         createSharedInbox(baseDir,'inbox',domain,port,httpPrefix) | 
					
						
							| 
									
										
										
										
											2019-07-12 09:52:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-20 10:10:33 +00:00
										 |  |  |     if not os.path.isdir(baseDir+'/cache'): | 
					
						
							|  |  |  |         os.mkdir(baseDir+'/cache') | 
					
						
							|  |  |  |     if not os.path.isdir(baseDir+'/cache/actors'): | 
					
						
							|  |  |  |         print('Creating actors cache') | 
					
						
							|  |  |  |         os.mkdir(baseDir+'/cache/actors') | 
					
						
							| 
									
										
										
										
											2019-08-20 12:39:59 +00:00
										 |  |  |     if not os.path.isdir(baseDir+'/cache/announce'): | 
					
						
							|  |  |  |         print('Creating announce cache') | 
					
						
							|  |  |  |         os.mkdir(baseDir+'/cache/announce') | 
					
						
							| 
									
										
										
										
											2019-08-20 10:10:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-20 11:51:29 +00:00
										 |  |  |     archiveDir=baseDir+'/archive' | 
					
						
							|  |  |  |     if not os.path.isdir(archiveDir): | 
					
						
							|  |  |  |         print('Creating archive') | 
					
						
							|  |  |  |         os.mkdir(archiveDir) | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2019-08-20 10:28:05 +00:00
										 |  |  |     print('Creating cache expiry thread') | 
					
						
							|  |  |  |     httpd.thrCache= \ | 
					
						
							|  |  |  |         threadWithTrace(target=expireCache, \ | 
					
						
							| 
									
										
										
										
											2019-08-20 11:51:29 +00:00
										 |  |  |                         args=(baseDir,httpd.personCache, \ | 
					
						
							|  |  |  |                               httpd.httpPrefix, \ | 
					
						
							|  |  |  |                               archiveDir, \ | 
					
						
							| 
									
										
										
										
											2019-08-20 11:52:12 +00:00
										 |  |  |                               httpd.maxPostsInBox),daemon=True) | 
					
						
							| 
									
										
										
										
											2019-08-20 10:28:05 +00:00
										 |  |  |     httpd.thrCache.start() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-12 09:52:06 +00:00
										 |  |  |     print('Creating inbox queue') | 
					
						
							| 
									
										
										
										
											2019-07-06 17:00:22 +00:00
										 |  |  |     httpd.thrInboxQueue= \ | 
					
						
							|  |  |  |         threadWithTrace(target=runInboxQueue, \ | 
					
						
							| 
									
										
										
										
											2019-08-14 20:12:27 +00:00
										 |  |  |                         args=(projectVersion, \ | 
					
						
							|  |  |  |                               baseDir,httpPrefix,httpd.sendThreads, \ | 
					
						
							| 
									
										
										
										
											2019-07-06 17:00:22 +00:00
										 |  |  |                               httpd.postLog,httpd.cachedWebfingers, \ | 
					
						
							|  |  |  |                               httpd.personCache,httpd.inboxQueue, \ | 
					
						
							|  |  |  |                               domain,port,useTor,httpd.federationList, \ | 
					
						
							| 
									
										
										
										
											2019-07-13 21:00:12 +00:00
										 |  |  |                               httpd.ocapAlways,maxReplies, \ | 
					
						
							| 
									
										
										
										
											2019-07-15 10:22:19 +00:00
										 |  |  |                               domainMaxPostsPerDay,accountMaxPostsPerDay, \ | 
					
						
							| 
									
										
										
										
											2019-07-17 18:13:45 +00:00
										 |  |  |                               allowDeletion,debug,httpd.acceptedCaps),daemon=True) | 
					
						
							| 
									
										
										
										
											2019-07-04 12:23:53 +00:00
										 |  |  |     httpd.thrInboxQueue.start() | 
					
						
							| 
									
										
										
										
											2019-07-13 09:37:17 +00:00
										 |  |  |     if clientToServer: | 
					
						
							| 
									
										
										
										
											2019-08-14 13:52:19 +00:00
										 |  |  |         print('Running ActivityPub client on ' + domain + ' port ' + str(proxyPort)) | 
					
						
							| 
									
										
										
										
											2019-07-13 09:37:17 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2019-08-14 13:52:19 +00:00
										 |  |  |         print('Running ActivityPub server on ' + domain + ' port ' + str(proxyPort)) | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |     httpd.serve_forever() |