manualapprove.py 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. __filename__ = "manualapprove.py"
  2. __author__ = "Bob Mottram"
  3. __license__ = "AGPL3+"
  4. __version__ = "1.1.0"
  5. __maintainer__ = "Bob Mottram"
  6. __email__ = "bob@freedombone.net"
  7. __status__ = "Production"
  8. import os
  9. from follow import followedAccountAccepts
  10. from follow import followedAccountRejects
  11. from follow import removeFromFollowRequests
  12. from utils import loadJson
  13. def manualDenyFollowRequest(session, baseDir: str,
  14. httpPrefix: str,
  15. nickname: str, domain: str, port: int,
  16. denyHandle: str,
  17. federationList: [],
  18. sendThreads: [], postLog: [],
  19. cachedWebfingers: {}, personCache: {},
  20. debug: bool,
  21. projectVersion: str) -> None:
  22. """Manually deny a follow request
  23. """
  24. handle = nickname + '@' + domain
  25. accountsDir = baseDir + '/accounts/' + handle
  26. # has this handle already been rejected?
  27. rejectedFollowsFilename = accountsDir + '/followrejects.txt'
  28. if os.path.isfile(rejectedFollowsFilename):
  29. if denyHandle in open(rejectedFollowsFilename).read():
  30. removeFromFollowRequests(baseDir, nickname, domain,
  31. denyHandle, debug)
  32. print(denyHandle + ' has already been rejected as a follower of ' +
  33. nickname)
  34. return
  35. removeFromFollowRequests(baseDir, nickname, domain, denyHandle, debug)
  36. # Store rejected follows
  37. rejectsFile = open(rejectedFollowsFilename, "a+")
  38. rejectsFile.write(denyHandle + '\n')
  39. rejectsFile.close()
  40. denyNickname = denyHandle.split('@')[0]
  41. denyDomain = \
  42. denyHandle.split('@')[1].replace('\n', '').replace('\r', '')
  43. denyPort = port
  44. if ':' in denyDomain:
  45. denyPort = denyDomain.split(':')[1]
  46. denyDomain = denyDomain.split(':')[0]
  47. followedAccountRejects(session, baseDir, httpPrefix,
  48. nickname, domain, port,
  49. denyNickname, denyDomain, denyPort,
  50. federationList,
  51. sendThreads, postLog,
  52. cachedWebfingers, personCache,
  53. debug, projectVersion)
  54. print('Follow request from ' + denyHandle + ' was denied.')
  55. def approveFollowerHandle(accountDir: str, approveHandle: str) -> None:
  56. """ Record manually approved handles so that if they unfollow and then
  57. re-follow later then they don't need to be manually approved again
  58. """
  59. approvedFilename = accountDir + '/approved.txt'
  60. if os.path.isfile(approvedFilename):
  61. if approveHandle not in open(approvedFilename).read():
  62. approvedFile = open(approvedFilename, "a+")
  63. approvedFile.write(approveHandle + '\n')
  64. approvedFile.close()
  65. else:
  66. approvedFile = open(approvedFilename, "w+")
  67. approvedFile.write(approveHandle + '\n')
  68. approvedFile.close()
  69. def manualApproveFollowRequest(session, baseDir: str,
  70. httpPrefix: str,
  71. nickname: str, domain: str, port: int,
  72. approveHandle: str,
  73. federationList: [],
  74. sendThreads: [], postLog: [],
  75. cachedWebfingers: {}, personCache: {},
  76. acceptedCaps: [],
  77. debug: bool,
  78. projectVersion: str) -> None:
  79. """Manually approve a follow request
  80. """
  81. handle = nickname + '@' + domain
  82. print('Manual follow accept: ' + handle +
  83. ' approving follow request from ' + approveHandle)
  84. accountDir = baseDir + '/accounts/' + handle
  85. approveFollowsFilename = accountDir + '/followrequests.txt'
  86. if not os.path.isfile(approveFollowsFilename):
  87. print('Manual follow accept: follow requests file ' +
  88. approveFollowsFilename + ' not found')
  89. return
  90. # is the handle in the requests file?
  91. if approveHandle not in open(approveFollowsFilename).read():
  92. print('Manual follow accept: ' + approveHandle +
  93. ' not in requests file ' + approveFollowsFilename)
  94. return
  95. approvefilenew = open(approveFollowsFilename + '.new', 'w+')
  96. updateApprovedFollowers = False
  97. followActivityfilename = None
  98. with open(approveFollowsFilename, 'r') as approvefile:
  99. for handleOfFollowRequester in approvefile:
  100. # is this the approved follow?
  101. if handleOfFollowRequester.startswith(approveHandle):
  102. handleOfFollowRequester = \
  103. handleOfFollowRequester.replace('\n', '').replace('\r', '')
  104. port2 = port
  105. if ':' in handleOfFollowRequester:
  106. port2Str = handleOfFollowRequester.split(':')[1]
  107. if port2Str.isdigit():
  108. port2 = int(port2Str)
  109. requestsDir = accountDir + '/requests'
  110. followActivityfilename = \
  111. requestsDir + '/' + handleOfFollowRequester + '.follow'
  112. if os.path.isfile(followActivityfilename):
  113. followJson = loadJson(followActivityfilename)
  114. if followJson:
  115. approveNickname = approveHandle.split('@')[0]
  116. approveDomain = approveHandle.split('@')[1]
  117. approveDomain = \
  118. approveDomain.replace('\n', '').replace('\r', '')
  119. approvePort = port2
  120. if ':' in approveDomain:
  121. approvePort = approveDomain.split(':')[1]
  122. approveDomain = approveDomain.split(':')[0]
  123. print('Manual follow accept: Sending Accept for ' +
  124. handle + ' follow request from ' +
  125. approveNickname + '@' + approveDomain)
  126. followedAccountAccepts(session, baseDir, httpPrefix,
  127. nickname, domain, port,
  128. approveNickname, approveDomain,
  129. approvePort,
  130. followJson['actor'],
  131. federationList,
  132. followJson, acceptedCaps,
  133. sendThreads, postLog,
  134. cachedWebfingers, personCache,
  135. debug, projectVersion, False)
  136. updateApprovedFollowers = True
  137. else:
  138. # this isn't the approved follow so it will remain
  139. # in the requests file
  140. approvefilenew.write(handleOfFollowRequester)
  141. approvefilenew.close()
  142. followersFilename = accountDir + '/followers.txt'
  143. if updateApprovedFollowers:
  144. # update the followers
  145. print('Manual follow accept: updating ' + followersFilename)
  146. if os.path.isfile(followersFilename):
  147. if approveHandle not in open(followersFilename).read():
  148. try:
  149. with open(followersFilename, 'r+') as followersFile:
  150. content = followersFile.read()
  151. followersFile.seek(0, 0)
  152. followersFile.write(approveHandle + '\n' + content)
  153. except Exception as e:
  154. print('WARN: Manual follow accept. ' +
  155. 'Failed to write entry to followers file ' + str(e))
  156. else:
  157. print('WARN: Manual follow accept: ' + approveHandle +
  158. ' already exists in ' + followersFilename)
  159. else:
  160. print('Manual follow accept: first follower accepted for ' +
  161. handle + ' is ' + approveHandle)
  162. followersFile = open(followersFilename, "w+")
  163. followersFile.write(approveHandle + '\n')
  164. followersFile.close()
  165. # only update the follow requests file if the follow is confirmed to be
  166. # in followers.txt
  167. if approveHandle in open(followersFilename).read():
  168. # mark this handle as approved for following
  169. approveFollowerHandle(accountDir, approveHandle)
  170. # update the follow requests with the handles not yet approved
  171. os.rename(approveFollowsFilename + '.new', approveFollowsFilename)
  172. # remove the .follow file
  173. if followActivityfilename:
  174. if os.path.isfile(followActivityfilename):
  175. os.remove(followActivityfilename)
  176. else:
  177. os.remove(approveFollowsFilename + '.new')