diff --git a/auth.py b/auth.py index 0d861c59f..9db4ad19c 100644 --- a/auth.py +++ b/auth.py @@ -132,17 +132,21 @@ def authorizeBasic(baseDir: str, path: str, authHeader: str, print('DEBUG: passwords file missing') return False providedPassword = plain.split(':')[1] - with open(passwordFile, 'r') as passfile: - for line in passfile: - if not line.startswith(nickname + ':'): - continue - storedPassword = \ - line.split(':')[1].replace('\n', '').replace('\r', '') - success = _verifyPassword(storedPassword, providedPassword) - if not success: - if debug: - print('DEBUG: Password check failed for ' + nickname) - return success + try: + with open(passwordFile, 'r') as passfile: + for line in passfile: + if not line.startswith(nickname + ':'): + continue + storedPassword = \ + line.split(':')[1].replace('\n', '').replace('\r', '') + success = _verifyPassword(storedPassword, providedPassword) + if not success: + if debug: + print('DEBUG: Password check failed for ' + nickname) + return success + except OSError: + print('EX: failed to open password file') + return False print('DEBUG: Did not find credentials for ' + nickname + ' in ' + passwordFile) return False @@ -272,15 +276,15 @@ def recordLoginFailure(baseDir: str, ipAddress: str, if not os.path.isfile(failureLog): writeType = 'w+' currTime = datetime.datetime.utcnow() + currTimeStr = currTime.strftime("%Y-%m-%d %H:%M:%SZ") try: with open(failureLog, writeType) as fp: # here we use a similar format to an ssh log, so that # systems such as fail2ban can parse it - fp.write(currTime.strftime("%Y-%m-%d %H:%M:%SZ") + ' ' + + fp.write(currTimeStr + ' ' + 'ip-127-0-0-1 sshd[20710]: ' + 'Disconnecting invalid user epicyon ' + ipAddress + ' port 443: ' + 'Too many authentication failures [preauth]\n') except OSError: print('EX: recordLoginFailure failed ' + str(failureLog)) - pass diff --git a/blocking.py b/blocking.py index 44bf77b33..f4e821a5b 100644 --- a/blocking.py +++ b/blocking.py @@ -94,11 +94,13 @@ def addBlock(baseDir: str, nickname: str, domain: str, try: with open(followingFilename, 'r') as followingFile: followingStr = followingFile.read() - followingStr = followingStr.replace(blockHandle + '\n', '') except OSError: print('EX: Unable to read following ' + followingFilename) return False + if followingStr: + followingStr = followingStr.replace(blockHandle + '\n', '') + try: with open(followingFilename, 'w+') as followingFile: followingFile.write(followingStr) @@ -114,11 +116,13 @@ def addBlock(baseDir: str, nickname: str, domain: str, try: with open(followersFilename, 'r') as followersFile: followersStr = followersFile.read() - followersStr = followersStr.replace(blockHandle + '\n', '') except OSError: print('EX: Unable to read followers ' + followersFilename) return False + if followersStr: + followersStr = followersStr.replace(blockHandle + '\n', '') + try: with open(followersFilename, 'w+') as followersFile: followersFile.write(followersStr) @@ -145,39 +149,51 @@ def removeGlobalBlock(baseDir: str, unblockHandle = unblockNickname + '@' + unblockDomain if os.path.isfile(unblockingFilename): if unblockHandle in open(unblockingFilename).read(): - with open(unblockingFilename, 'r') as fp: - try: + try: + with open(unblockingFilename, 'r') as fp: with open(unblockingFilename + '.new', 'w+') as fpnew: for line in fp: handle = \ line.replace('\n', '').replace('\r', '') if unblockHandle not in line: fpnew.write(handle + '\n') - except OSError as e: - print('EX: failed to remove global block ' + - unblockingFilename + ' ' + str(e)) - return False + except OSError as e: + print('EX: failed to remove global block ' + + unblockingFilename + ' ' + str(e)) + return False + if os.path.isfile(unblockingFilename + '.new'): - os.rename(unblockingFilename + '.new', unblockingFilename) + try: + os.rename(unblockingFilename + '.new', + unblockingFilename) + except OSError: + print('EX: unable to rename ' + unblockingFilename) + return False return True else: unblockHashtag = unblockNickname if os.path.isfile(unblockingFilename): if unblockHashtag + '\n' in open(unblockingFilename).read(): - with open(unblockingFilename, 'r') as fp: - try: + try: + with open(unblockingFilename, 'r') as fp: with open(unblockingFilename + '.new', 'w+') as fpnew: for line in fp: blockLine = \ line.replace('\n', '').replace('\r', '') if unblockHashtag not in line: fpnew.write(blockLine + '\n') - except OSError as e: - print('EX: failed to remove global hashtag block ' + - unblockingFilename + ' ' + str(e)) - return False + except OSError as e: + print('EX: failed to remove global hashtag block ' + + unblockingFilename + ' ' + str(e)) + return False + if os.path.isfile(unblockingFilename + '.new'): - os.rename(unblockingFilename + '.new', unblockingFilename) + try: + os.rename(unblockingFilename + '.new', + unblockingFilename) + except OSError: + print('EX: unable to rename 2 ' + unblockingFilename) + return False return True return False @@ -191,19 +207,24 @@ def removeBlock(baseDir: str, nickname: str, domain: str, unblockHandle = unblockNickname + '@' + unblockDomain if os.path.isfile(unblockingFilename): if unblockHandle in open(unblockingFilename).read(): - with open(unblockingFilename, 'r') as fp: - try: + try: + with open(unblockingFilename, 'r') as fp: with open(unblockingFilename + '.new', 'w+') as fpnew: for line in fp: handle = line.replace('\n', '').replace('\r', '') if unblockHandle not in line: fpnew.write(handle + '\n') - except OSError as e: - print('EX: failed to remove block ' + - unblockingFilename + ' ' + str(e)) - return False + except OSError as e: + print('EX: failed to remove block ' + + unblockingFilename + ' ' + str(e)) + return False + if os.path.isfile(unblockingFilename + '.new'): - os.rename(unblockingFilename + '.new', unblockingFilename) + try: + os.rename(unblockingFilename + '.new', unblockingFilename) + except OSError: + print('EX: unable to rename 3 ' + unblockingFilename) + return False return True return False @@ -237,8 +258,11 @@ def getDomainBlocklist(baseDir: str) -> str: globalBlockingFilename = baseDir + '/accounts/blocking.txt' if not os.path.isfile(globalBlockingFilename): return blockedStr - with open(globalBlockingFilename, 'r') as fpBlocked: - blockedStr += fpBlocked.read() + try: + with open(globalBlockingFilename, 'r') as fpBlocked: + blockedStr += fpBlocked.read() + except OSError: + print('EX: unable to read ' + globalBlockingFilename) return blockedStr @@ -258,14 +282,17 @@ def updateBlockedCache(baseDir: str, globalBlockingFilename = baseDir + '/accounts/blocking.txt' if not os.path.isfile(globalBlockingFilename): return blockedCacheLastUpdated - with open(globalBlockingFilename, 'r') as fpBlocked: - blockedLines = fpBlocked.readlines() - # remove newlines - for index in range(len(blockedLines)): - blockedLines[index] = blockedLines[index].replace('\n', '') - # update the cache - blockedCache.clear() - blockedCache += blockedLines + try: + with open(globalBlockingFilename, 'r') as fpBlocked: + blockedLines = fpBlocked.readlines() + # remove newlines + for index in range(len(blockedLines)): + blockedLines[index] = blockedLines[index].replace('\n', '') + # update the cache + blockedCache.clear() + blockedCache += blockedLines + except OSError as e: + print('EX: unable to read ' + globalBlockingFilename + ' ' + str(e)) return currTime @@ -305,13 +332,17 @@ def isBlockedDomain(baseDir: str, domain: str, # instance block list globalBlockingFilename = baseDir + '/accounts/blocking.txt' if os.path.isfile(globalBlockingFilename): - with open(globalBlockingFilename, 'r') as fpBlocked: - blockedStr = fpBlocked.read() - if '*@' + domain in blockedStr: - return True - if shortDomain: - if '*@' + shortDomain in blockedStr: + try: + with open(globalBlockingFilename, 'r') as fpBlocked: + blockedStr = fpBlocked.read() + if '*@' + domain in blockedStr: return True + if shortDomain: + if '*@' + shortDomain in blockedStr: + return True + except OSError as e: + print('EX: unable to read ' + globalBlockingFilename + + ' ' + str(e)) else: allowFilename = baseDir + '/accounts/allowedinstances.txt' # instance allow list @@ -572,10 +603,10 @@ def mutePost(baseDir: str, nickname: str, domain: str, port: int, try: with open(postFilename + '.muted', 'w+') as muteFile: muteFile.write('\n') - print('MUTE: ' + postFilename + '.muted file added') except OSError: print('EX: Failed to save mute file ' + postFilename + '.muted') return + print('MUTE: ' + postFilename + '.muted file added') # if the post is in the recent posts cache then mark it as muted if recentPostsCache.get('index'): @@ -886,15 +917,19 @@ def setBrochMode(baseDir: str, domainFull: str, enabled: bool) -> None: followingFilename = accountDir + '/' + followFileType if not os.path.isfile(followingFilename): continue - with open(followingFilename, 'r') as f: - followList = f.readlines() - for handle in followList: - if '@' not in handle: - continue - handle = handle.replace('\n', '') - handleDomain = handle.split('@')[1] - if handleDomain not in allowedDomains: - allowedDomains.append(handleDomain) + try: + with open(followingFilename, 'r') as f: + followList = f.readlines() + for handle in followList: + if '@' not in handle: + continue + handle = handle.replace('\n', '') + handleDomain = handle.split('@')[1] + if handleDomain not in allowedDomains: + allowedDomains.append(handleDomain) + except OSError as e: + print('EX: failed to read ' + followingFilename + + ' ' + str(e)) break # write the allow file diff --git a/blog.py b/blog.py index de240103c..7566e49e7 100644 --- a/blog.py +++ b/blog.py @@ -72,20 +72,24 @@ def _noOfBlogReplies(baseDir: str, httpPrefix: str, translate: {}, removals = [] replies = 0 lines = [] - with open(postFilename, 'r') as f: - lines = f.readlines() - for replyPostId in lines: - replyPostId = replyPostId.replace('\n', '').replace('\r', '') - replyPostId = replyPostId.replace('.json', '') - if locatePost(baseDir, nickname, domain, replyPostId): - replyPostId = replyPostId.replace('.replies', '') - replies += \ - 1 + _noOfBlogReplies(baseDir, httpPrefix, translate, - nickname, domain, domainFull, - replyPostId, depth+1) - else: - # remove post which no longer exists - removals.append(replyPostId) + try: + with open(postFilename, 'r') as f: + lines = f.readlines() + except OSError: + print('EX: failed to read blog ' + postFilename) + + for replyPostId in lines: + replyPostId = replyPostId.replace('\n', '').replace('\r', '') + replyPostId = replyPostId.replace('.json', '') + if locatePost(baseDir, nickname, domain, replyPostId): + replyPostId = replyPostId.replace('.replies', '') + replies += \ + 1 + _noOfBlogReplies(baseDir, httpPrefix, translate, + nickname, domain, domainFull, + replyPostId, depth+1) + else: + # remove post which no longer exists + removals.append(replyPostId) # remove posts from .replies file if they don't exist if lines and removals: @@ -135,12 +139,21 @@ def _getBlogReplies(baseDir: str, httpPrefix: str, translate: {}, '/postcache/' + \ postId.replace('/', '#') + '.html' if os.path.isfile(postFilename): - with open(postFilename, 'r') as postFile: - return postFile.read() + '\n' + try: + with open(postFilename, 'r') as postFile: + return postFile.read() + '\n' + except OSError: + print('EX: unable to read blog 3 ' + postFilename) return '' - with open(postFilename, 'r') as f: - lines = f.readlines() + lines = [] + try: + with open(postFilename, 'r') as f: + lines = f.readlines() + except OSError: + print('EX: unable to read blog 4 ' + postFilename) + + if lines: repliesStr = '' for replyPostId in lines: replyPostId = replyPostId.replace('\n', '').replace('\r', '') @@ -151,8 +164,11 @@ def _getBlogReplies(baseDir: str, httpPrefix: str, translate: {}, replyPostId.replace('/', '#') + '.html' if not os.path.isfile(postFilename): continue - with open(postFilename, 'r') as postFile: - repliesStr += postFile.read() + '\n' + try: + with open(postFilename, 'r') as postFile: + repliesStr += postFile.read() + '\n' + except OSError: + print('EX: unable to read blog replies ' + postFilename) rply = _getBlogReplies(baseDir, httpPrefix, translate, nickname, domain, domainFull, replyPostId, depth+1) @@ -770,8 +786,11 @@ def htmlEditBlog(mediaInstance: bool, translate: {}, editBlogText = '' + translate['Write your post text below.'] + '' if os.path.isfile(baseDir + '/accounts/newpost.txt'): - with open(baseDir + '/accounts/newpost.txt', 'r') as file: - editBlogText = '

' + file.read() + '

' + try: + with open(baseDir + '/accounts/newpost.txt', 'r') as file: + editBlogText = '

' + file.read() + '

' + except OSError: + print('EX: unable to read ' + baseDir + '/accounts/newpost.txt') cssFilename = baseDir + '/epicyon-profile.css' if os.path.isfile(baseDir + '/epicyon.css'): diff --git a/bookmarks.py b/bookmarks.py index 197e8aaeb..8dcb18d95 100644 --- a/bookmarks.py +++ b/bookmarks.py @@ -71,8 +71,12 @@ def undoBookmarksCollectionEntry(recentPostsCache: {}, if bookmarkIndex not in open(bookmarksIndexFilename).read(): return indexStr = '' - with open(bookmarksIndexFilename, 'r') as indexFile: - indexStr = indexFile.read().replace(bookmarkIndex + '\n', '') + try: + with open(bookmarksIndexFilename, 'r') as indexFile: + indexStr = indexFile.read().replace(bookmarkIndex + '\n', '') + except OSError: + print('EX: unable to read ' + bookmarksIndexFilename) + if indexStr: try: with open(bookmarksIndexFilename, 'w+') as bookmarksIndexFile: bookmarksIndexFile.write(indexStr) diff --git a/categories.py b/categories.py index 25db73113..e9dca2153 100644 --- a/categories.py +++ b/categories.py @@ -23,10 +23,14 @@ def getHashtagCategory(baseDir: str, hashtag: str) -> str: if not os.path.isfile(categoryFilename): return '' - with open(categoryFilename, 'r') as fp: - categoryStr = fp.read() - if categoryStr: - return categoryStr + categoryStr = None + try: + with open(categoryFilename, 'r') as fp: + categoryStr = fp.read() + except OSError: + print('EX: unable to read category ' + categoryFilename) + if categoryStr: + return categoryStr return '' @@ -161,15 +165,21 @@ def setHashtagCategory(baseDir: str, hashtag: str, category: str, # don't overwrite any existing categories if os.path.isfile(categoryFilename): return False + + categoryWritten = False try: with open(categoryFilename, 'w+') as fp: fp.write(category) - if update: - updateHashtagCategories(baseDir) - return True + categoryWritten = True except OSError as e: print('EX: unable to write category ' + categoryFilename + ' ' + str(e)) + + if categoryWritten: + if update: + updateHashtagCategories(baseDir) + return True + return False diff --git a/city.py b/city.py index b486c2de0..3f8c0f3af 100644 --- a/city.py +++ b/city.py @@ -196,21 +196,28 @@ def spoofGeolocation(baseDir: str, default_latdirection, default_longdirection, "", "", 0) cities = [] - with open(locationsFilename, 'r') as f: - cities = f.readlines() + try: + with open(locationsFilename, 'r') as f: + cities = f.readlines() + except OSError: + print('EX: unable to read locations ' + locationsFilename) nogo = [] if nogoList: nogo = nogoList else: if os.path.isfile(nogoFilename): - with open(nogoFilename, 'r') as f: - nogoList = f.readlines() - for line in nogoList: - if line.startswith(city + ':'): - polygon = parseNogoString(line) - if polygon: - nogo.append(polygon) + nogoList = [] + try: + with open(nogoFilename, 'r') as f: + nogoList = f.readlines() + except OSError: + print('EX: unable to read ' + nogoFilename) + for line in nogoList: + if line.startswith(city + ':'): + polygon = parseNogoString(line) + if polygon: + nogo.append(polygon) city = city.lower() for cityName in cities: @@ -295,8 +302,11 @@ def getSpoofedCity(city: str, baseDir: str, nickname: str, domain: str) -> str: city = '' cityFilename = acctDir(baseDir, nickname, domain) + '/city.txt' if os.path.isfile(cityFilename): - with open(cityFilename, 'r') as fp: - city = fp.read().replace('\n', '') + try: + with open(cityFilename, 'r') as fp: + city = fp.read().replace('\n', '') + except OSError: + print('EX: unable to read ' + cityFilename) return city diff --git a/content.py b/content.py index e4dcfe99a..b32c9850d 100644 --- a/content.py +++ b/content.py @@ -178,9 +178,14 @@ def dangerousCSS(filename: str, allowLocalNetworkAccess: bool) -> bool: if not os.path.isfile(filename): return False - with open(filename, 'r') as fp: - content = fp.read().lower() + content = None + try: + with open(filename, 'r') as fp: + content = fp.read().lower() + except OSError: + print('EX: unable to read css file ' + filename) + if content: cssMatches = ('behavior:', ':expression', '?php', '.php', 'google', 'regexp', 'localhost', '127.0.', '192.168', '10.0.', '@import') @@ -221,8 +226,11 @@ def switchWords(baseDir: str, nickname: str, domain: str, content: str, acctDir(baseDir, nickname, domain) + '/replacewords.txt' if not os.path.isfile(switchWordsFilename): return content - with open(switchWordsFilename, 'r') as fp: - rules = fp.readlines() + try: + with open(switchWordsFilename, 'r') as fp: + rules = fp.readlines() + except OSError: + print('EX: unable to read switches ' + switchWordsFilename) for line in rules: replaceStr = line.replace('\n', '').replace('\r', '') @@ -779,8 +787,11 @@ def _loadAutoTags(baseDir: str, nickname: str, domain: str) -> []: filename = acctDir(baseDir, nickname, domain) + '/autotags.txt' if not os.path.isfile(filename): return [] - with open(filename, 'r') as f: - return f.readlines() + try: + with open(filename, 'r') as f: + return f.readlines() + except OSError: + print('EX: unable to read auto tags ' + filename) return [] @@ -853,12 +864,16 @@ def addHtmlTags(baseDir: str, httpPrefix: str, petnames = None if '@' in words: if os.path.isfile(followingFilename): - with open(followingFilename, 'r') as f: - following = f.readlines() - for handle in following: - pet = getPetName(baseDir, nickname, domain, handle) - if pet: - petnames.append(pet + '\n') + following = [] + try: + with open(followingFilename, 'r') as f: + following = f.readlines() + except OSError: + print('EX: unable to read ' + followingFilename) + for handle in following: + pet = getPetName(baseDir, nickname, domain, handle) + if pet: + petnames.append(pet + '\n') # extract mentions and tags from words longWordsList = [] diff --git a/daemon.py b/daemon.py index dac884889..88a3085ab 100644 --- a/daemon.py +++ b/daemon.py @@ -2355,13 +2355,16 @@ class PubServer(BaseHTTPRequestHandler): else: if os.path.isdir(accountDir): nwFilename = newswireBlockedFilename + nwWritten = False try: with open(nwFilename, 'w+') as noNewswireFile: noNewswireFile.write('\n') - refreshNewswire(self.server.baseDir) + nwWritten = True except OSError as e: print('EX: unable to write ' + nwFilename + ' ' + str(e)) + if nwWritten: + refreshNewswire(self.server.baseDir) usersPathStr = \ usersPath + '/' + self.server.defaultTimeline + \ '?page=' + str(pageNumber) @@ -2398,13 +2401,16 @@ class PubServer(BaseHTTPRequestHandler): else: if os.path.isdir(accountDir): featFilename = featuresBlockedFilename + featWritten = False try: with open(featFilename, 'w+') as noFeaturesFile: noFeaturesFile.write('\n') - refreshNewswire(self.server.baseDir) + featWritten = True except OSError as e: print('EX: unable to write ' + featFilename + ' ' + str(e)) + if featWritten: + refreshNewswire(self.server.baseDir) usersPathStr = \ usersPath + '/' + self.server.defaultTimeline + \ '?page=' + str(pageNumber) @@ -3906,8 +3912,11 @@ class PubServer(BaseHTTPRequestHandler): if fields.get('editedLinks'): linksStr = fields['editedLinks'] - with open(linksFilename, 'w+') as linksFile: - linksFile.write(linksStr) + try: + with open(linksFilename, 'w+') as linksFile: + linksFile.write(linksStr) + except OSError: + print('EX: _linksUpdate unable to write ' + linksFilename) else: if os.path.isfile(linksFilename): try: @@ -3923,8 +3932,11 @@ class PubServer(BaseHTTPRequestHandler): aboutStr = fields['editedAbout'] if not dangerousMarkup(aboutStr, allowLocalNetworkAccess): - with open(aboutFilename, 'w+') as aboutFile: - aboutFile.write(aboutStr) + try: + with open(aboutFilename, 'w+') as aboutFile: + aboutFile.write(aboutStr) + except OSError: + print('EX: unable to write about ' + aboutFilename) else: if os.path.isfile(aboutFilename): try: @@ -3937,8 +3949,11 @@ class PubServer(BaseHTTPRequestHandler): TOSStr = fields['editedTOS'] if not dangerousMarkup(TOSStr, allowLocalNetworkAccess): - with open(TOSFilename, 'w+') as TOSFile: - TOSFile.write(TOSStr) + try: + with open(TOSFilename, 'w+') as TOSFile: + TOSFile.write(TOSStr) + except OSError: + print('EX: unable to write TOS ' + TOSFilename) else: if os.path.isfile(TOSFilename): try: