| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  | __filename__ = "roles.py" | 
					
						
							|  |  |  | __author__ = "Bob Mottram" | 
					
						
							|  |  |  | __license__ = "AGPL3+" | 
					
						
							|  |  |  | __version__ = "1.1.0" | 
					
						
							|  |  |  | __maintainer__ = "Bob Mottram" | 
					
						
							|  |  |  | __email__ = "bob@freedombone.net" | 
					
						
							|  |  |  | __status__ = "Production" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  | import os | 
					
						
							|  |  |  | from webfinger import webfingerHandle | 
					
						
							|  |  |  | from auth import createBasicAuthHeader | 
					
						
							|  |  |  | from posts import getPersonBox | 
					
						
							|  |  |  | from session import postJson | 
					
						
							|  |  |  | from utils import getNicknameFromActor | 
					
						
							|  |  |  | from utils import getDomainFromActor | 
					
						
							| 
									
										
										
										
											2019-10-22 11:55:06 +00:00
										 |  |  | from utils import loadJson | 
					
						
							|  |  |  | from utils import saveJson | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-12 21:20:47 +00:00
										 |  |  | def clearModeratorStatus(baseDir: str) -> None: | 
					
						
							|  |  |  |     """Removes moderator status from all accounts
 | 
					
						
							|  |  |  |     This could be slow if there are many users, but only happens | 
					
						
							|  |  |  |     rarely when moderators are appointed or removed | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     directory = os.fsencode(baseDir + '/accounts/') | 
					
						
							| 
									
										
										
										
											2019-09-27 12:09:04 +00:00
										 |  |  |     for f in os.scandir(directory): | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |         f = f.name | 
					
						
							|  |  |  |         filename = os.fsdecode(f) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |         if filename.endswith(".json") and '@' in filename: | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |             filename = os.path.join(baseDir + '/accounts/', filename) | 
					
						
							| 
									
										
										
										
											2019-08-12 21:20:47 +00:00
										 |  |  |             if '"moderator"' in open(filename).read(): | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |                 actorJson = loadJson(filename) | 
					
						
							| 
									
										
										
										
											2019-09-30 22:39:02 +00:00
										 |  |  |                 if actorJson: | 
					
						
							| 
									
										
										
										
											2019-08-12 21:20:47 +00:00
										 |  |  |                     if actorJson['roles'].get('instance'): | 
					
						
							|  |  |  |                         if 'moderator' in actorJson['roles']['instance']: | 
					
						
							|  |  |  |                             actorJson['roles']['instance'].remove('moderator') | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |                             saveJson(actorJson, filename) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-12 21:20:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-11 19:42:21 +00:00
										 |  |  | def clearEditorStatus(baseDir: str) -> None: | 
					
						
							|  |  |  |     """Removes editor status from all accounts
 | 
					
						
							|  |  |  |     This could be slow if there are many users, but only happens | 
					
						
							|  |  |  |     rarely when editors are appointed or removed | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     directory = os.fsencode(baseDir + '/accounts/') | 
					
						
							|  |  |  |     for f in os.scandir(directory): | 
					
						
							|  |  |  |         f = f.name | 
					
						
							|  |  |  |         filename = os.fsdecode(f) | 
					
						
							|  |  |  |         if filename.endswith(".json") and '@' in filename: | 
					
						
							|  |  |  |             filename = os.path.join(baseDir + '/accounts/', filename) | 
					
						
							|  |  |  |             if '"editor"' in open(filename).read(): | 
					
						
							|  |  |  |                 actorJson = loadJson(filename) | 
					
						
							|  |  |  |                 if actorJson: | 
					
						
							|  |  |  |                     if actorJson['roles'].get('instance'): | 
					
						
							|  |  |  |                         if 'editor' in actorJson['roles']['instance']: | 
					
						
							|  |  |  |                             actorJson['roles']['instance'].remove('editor') | 
					
						
							|  |  |  |                             saveJson(actorJson, filename) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  | def addModerator(baseDir: str, nickname: str, domain: str) -> None: | 
					
						
							| 
									
										
										
										
											2019-08-11 11:25:27 +00:00
										 |  |  |     """Adds a moderator nickname to the file
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2019-08-12 21:20:47 +00:00
										 |  |  |     if ':' in domain: | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |         domain = domain.split(':')[0] | 
					
						
							|  |  |  |     moderatorsFile = baseDir + '/accounts/moderators.txt' | 
					
						
							| 
									
										
										
										
											2019-08-11 11:25:27 +00:00
										 |  |  |     if os.path.isfile(moderatorsFile): | 
					
						
							|  |  |  |         # is this nickname already in the file? | 
					
						
							|  |  |  |         with open(moderatorsFile, "r") as f: | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |             lines = f.readlines() | 
					
						
							| 
									
										
										
										
											2019-08-11 11:25:27 +00:00
										 |  |  |         for moderator in lines: | 
					
						
							| 
									
										
										
										
											2020-05-22 11:32:38 +00:00
										 |  |  |             moderator = moderator.strip('\n').strip('\r') | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |             if moderator == nickname: | 
					
						
							| 
									
										
										
										
											2019-08-11 11:25:27 +00:00
										 |  |  |                 return | 
					
						
							|  |  |  |         lines.append(nickname) | 
					
						
							| 
									
										
										
										
											2020-08-29 11:14:19 +00:00
										 |  |  |         with open(moderatorsFile, 'w+') as f: | 
					
						
							| 
									
										
										
										
											2019-08-11 11:25:27 +00:00
										 |  |  |             for moderator in lines: | 
					
						
							| 
									
										
										
										
											2020-05-22 11:32:38 +00:00
										 |  |  |                 moderator = moderator.strip('\n').strip('\r') | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |                 if len(moderator) > 1: | 
					
						
							|  |  |  |                     if os.path.isdir(baseDir + '/accounts/' + | 
					
						
							|  |  |  |                                      moderator + '@' + domain): | 
					
						
							|  |  |  |                         f.write(moderator + '\n') | 
					
						
							| 
									
										
										
										
											2019-08-11 11:27:29 +00:00
										 |  |  |     else: | 
					
						
							|  |  |  |         with open(moderatorsFile, "w+") as f: | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |             if os.path.isdir(baseDir + '/accounts/' + | 
					
						
							|  |  |  |                              nickname + '@' + domain): | 
					
						
							|  |  |  |                 f.write(nickname + '\n') | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def removeModerator(baseDir: str, nickname: str): | 
					
						
							| 
									
										
										
										
											2019-08-11 11:25:27 +00:00
										 |  |  |     """Removes a moderator nickname from the file
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     moderatorsFile = baseDir + '/accounts/moderators.txt' | 
					
						
							| 
									
										
										
										
											2019-08-11 11:25:27 +00:00
										 |  |  |     if not os.path.isfile(moderatorsFile): | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     with open(moderatorsFile, "r") as f: | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |         lines = f.readlines() | 
					
						
							| 
									
										
										
										
											2020-08-29 11:14:19 +00:00
										 |  |  |     with open(moderatorsFile, 'w+') as f: | 
					
						
							| 
									
										
										
										
											2019-08-11 11:25:27 +00:00
										 |  |  |         for moderator in lines: | 
					
						
							| 
									
										
										
										
											2020-05-22 11:32:38 +00:00
										 |  |  |             moderator = moderator.strip('\n').strip('\r') | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |             if len(moderator) > 1 and moderator != nickname: | 
					
						
							|  |  |  |                 f.write(moderator + '\n') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-11 11:25:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  | def setRole(baseDir: str, nickname: str, domain: str, | 
					
						
							|  |  |  |             project: str, role: str) -> bool: | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |     """Set a person's role within a project
 | 
					
						
							|  |  |  |     Setting the role to an empty string or None will remove it | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     # avoid giant strings | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     if len(role) > 128 or len(project) > 128: | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     actorFilename = baseDir + '/accounts/' + \ | 
					
						
							|  |  |  |         nickname + '@' + domain + '.json' | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |     if not os.path.isfile(actorFilename): | 
					
						
							|  |  |  |         return False | 
					
						
							| 
									
										
										
										
											2019-09-30 22:39:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     actorJson = loadJson(actorFilename) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |     if actorJson: | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |         if role: | 
					
						
							| 
									
										
										
										
											2019-08-11 11:25:27 +00:00
										 |  |  |             # add the role | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |             if project == 'instance' and 'role' == 'moderator': | 
					
						
							|  |  |  |                 addModerator(baseDir, nickname, domain) | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |             if actorJson['roles'].get(project): | 
					
						
							|  |  |  |                 if role not in actorJson['roles'][project]: | 
					
						
							|  |  |  |                     actorJson['roles'][project].append(role) | 
					
						
							|  |  |  |             else: | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |                 actorJson['roles'][project] = [role] | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2019-08-11 11:25:27 +00:00
										 |  |  |             # remove the role | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |             if project == 'instance': | 
					
						
							|  |  |  |                 removeModerator(baseDir, nickname) | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |             if actorJson['roles'].get(project): | 
					
						
							|  |  |  |                 actorJson['roles'][project].remove(role) | 
					
						
							|  |  |  |                 # if the project contains no roles then remove it | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |                 if len(actorJson['roles'][project]) == 0: | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |                     del actorJson['roles'][project] | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |         saveJson(actorJson, actorFilename) | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |     return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def getRoles(baseDir: str, nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |              project: str) -> []: | 
					
						
							|  |  |  |     """Returns the roles for a given person on a given project
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     actorFilename = baseDir + '/accounts/' + \ | 
					
						
							|  |  |  |         nickname + '@' + domain + '.json' | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |     if not os.path.isfile(actorFilename): | 
					
						
							|  |  |  |         return False | 
					
						
							| 
									
										
										
										
											2019-09-30 22:39:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     actorJson = loadJson(actorFilename) | 
					
						
							| 
									
										
										
										
											2019-09-30 22:39:02 +00:00
										 |  |  |     if actorJson: | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |         if not actorJson.get('roles'): | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  |         if not actorJson['roles'].get(project): | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  |         return actorJson['roles'][project] | 
					
						
							|  |  |  |     return None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def outboxDelegate(baseDir: str, authenticatedNickname: str, | 
					
						
							|  |  |  |                    messageJson: {}, debug: bool) -> bool: | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |     """Handles receiving a delegation request
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not messageJson.get('type'): | 
					
						
							| 
									
										
										
										
											2019-07-18 16:21:26 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     if not messageJson['type'] == 'Delegate': | 
					
						
							| 
									
										
										
										
											2019-07-18 16:21:26 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |     if not messageJson.get('object'): | 
					
						
							| 
									
										
										
										
											2019-07-18 16:21:26 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |     if not isinstance(messageJson['object'], dict): | 
					
						
							| 
									
										
										
										
											2019-07-18 16:21:26 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |     if not messageJson['object'].get('type'): | 
					
						
							| 
									
										
										
										
											2019-07-18 16:21:26 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     if not messageJson['object']['type'] == 'Role': | 
					
						
							| 
									
										
										
										
											2019-07-18 16:21:26 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |     if not messageJson['object'].get('object'): | 
					
						
							| 
									
										
										
										
											2019-07-18 16:21:26 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |     if not messageJson['object'].get('actor'): | 
					
						
							| 
									
										
										
										
											2019-07-18 16:21:26 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |     if not isinstance(messageJson['object']['object'], str): | 
					
						
							| 
									
										
										
										
											2019-07-18 16:21:26 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |     if ';' not in messageJson['object']['object']: | 
					
						
							|  |  |  |         print('WARN: No ; separator between project and role') | 
					
						
							| 
									
										
										
										
											2019-07-18 16:21:26 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     delegatorNickname = getNicknameFromActor(messageJson['actor']) | 
					
						
							|  |  |  |     if delegatorNickname != authenticatedNickname: | 
					
						
							| 
									
										
										
										
											2019-07-19 10:01:24 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     domain, port = getDomainFromActor(messageJson['actor']) | 
					
						
							|  |  |  |     project = messageJson['object']['object'].split(';')[0].strip() | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-18 16:21:26 +00:00
										 |  |  |     # instance delegators can delagate to other projects | 
					
						
							|  |  |  |     # than their own | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     canDelegate = False | 
					
						
							|  |  |  |     delegatorRoles = getRoles(baseDir, delegatorNickname, | 
					
						
							|  |  |  |                               domain, 'instance') | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |     if delegatorRoles: | 
					
						
							| 
									
										
										
										
											2019-07-18 16:21:26 +00:00
										 |  |  |         if 'delegator' in delegatorRoles: | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |             canDelegate = True | 
					
						
							| 
									
										
										
										
											2019-07-18 16:21:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     if not canDelegate: | 
					
						
							|  |  |  |         canDelegate = True | 
					
						
							| 
									
										
										
										
											2019-07-18 16:21:26 +00:00
										 |  |  |         # non-instance delegators can only delegate within their project | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |         delegatorRoles = getRoles(baseDir, delegatorNickname, | 
					
						
							|  |  |  |                                   domain, project) | 
					
						
							| 
									
										
										
										
											2019-07-18 16:21:26 +00:00
										 |  |  |         if delegatorRoles: | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |             if 'delegator' not in delegatorRoles: | 
					
						
							| 
									
										
										
										
											2019-07-18 16:21:26 +00:00
										 |  |  |                 return False | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     if not canDelegate: | 
					
						
							| 
									
										
										
										
											2019-07-18 16:21:26 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     nickname = getNicknameFromActor(messageJson['object']['actor']) | 
					
						
							| 
									
										
										
										
											2019-09-02 09:43:43 +00:00
										 |  |  |     if not nickname: | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |         print('WARN: unable to find nickname in ' + | 
					
						
							|  |  |  |               messageJson['object']['actor']) | 
					
						
							| 
									
										
										
										
											2019-09-02 09:43:43 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     role = \ | 
					
						
							|  |  |  |         messageJson['object']['object'].split(';')[1].strip().lower() | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-18 16:43:48 +00:00
										 |  |  |     if not role: | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |         setRole(baseDir, nickname, domain, project, None) | 
					
						
							| 
									
										
										
										
											2019-07-18 16:43:48 +00:00
										 |  |  |         return True | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |     # what roles is this person already assigned to? | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     existingRoles = getRoles(baseDir, nickname, domain, project) | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |     if existingRoles: | 
					
						
							|  |  |  |         if role in existingRoles: | 
					
						
							| 
									
										
										
										
											2019-07-18 16:21:26 +00:00
										 |  |  |             if debug: | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |                 print(nickname + '@' + domain + | 
					
						
							|  |  |  |                       ' is already assigned to the role ' + | 
					
						
							|  |  |  |                       role + ' within the project ' + project) | 
					
						
							| 
									
										
										
										
											2019-07-18 16:21:26 +00:00
										 |  |  |             return False | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     setRole(baseDir, nickname, domain, project, role) | 
					
						
							| 
									
										
										
										
											2019-07-18 16:21:26 +00:00
										 |  |  |     if debug: | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |         print(nickname + '@' + domain + | 
					
						
							|  |  |  |               ' assigned to the role ' + role + | 
					
						
							|  |  |  |               ' within the project ' + project) | 
					
						
							| 
									
										
										
										
											2019-07-18 16:21:26 +00:00
										 |  |  |     return True | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def sendRoleViaServer(baseDir: str, session, | 
					
						
							|  |  |  |                       delegatorNickname: str, password: str, | 
					
						
							|  |  |  |                       delegatorDomain: str, delegatorPort: int, | 
					
						
							|  |  |  |                       httpPrefix: str, nickname: str, | 
					
						
							|  |  |  |                       project: str, role: str, | 
					
						
							|  |  |  |                       cachedWebfingers: {}, personCache: {}, | 
					
						
							|  |  |  |                       debug: bool, projectVersion: str) -> {}: | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |     """A delegator creates a role for a person via c2s
 | 
					
						
							| 
									
										
										
										
											2019-07-18 16:43:48 +00:00
										 |  |  |     Setting role to an empty string or None removes the role | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |     """
 | 
					
						
							|  |  |  |     if not session: | 
					
						
							|  |  |  |         print('WARN: No session for sendRoleViaServer') | 
					
						
							|  |  |  |         return 6 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     delegatorDomainFull = delegatorDomain | 
					
						
							|  |  |  |     if delegatorPort: | 
					
						
							|  |  |  |         if delegatorPort != 80 and delegatorPort != 443: | 
					
						
							| 
									
										
										
										
											2019-08-16 20:35:11 +00:00
										 |  |  |             if ':' not in delegatorDomain: | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |                 delegatorDomainFull = \ | 
					
						
							|  |  |  |                     delegatorDomain + ':' + str(delegatorPort) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     toUrl = \ | 
					
						
							|  |  |  |         httpPrefix + '://' + delegatorDomainFull + '/users/' + nickname | 
					
						
							|  |  |  |     ccUrl = \ | 
					
						
							|  |  |  |         httpPrefix + '://' + delegatorDomainFull + '/users/' + \ | 
					
						
							|  |  |  |         delegatorNickname + '/followers' | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-18 16:43:48 +00:00
										 |  |  |     if role: | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |         roleStr = project.lower() + ';' + role.lower() | 
					
						
							| 
									
										
										
										
											2019-07-18 16:43:48 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |         roleStr = project.lower() + ';' | 
					
						
							|  |  |  |     actor = \ | 
					
						
							|  |  |  |         httpPrefix + '://' + delegatorDomainFull + \ | 
					
						
							|  |  |  |         '/users/' + delegatorNickname | 
					
						
							|  |  |  |     delegateActor = \ | 
					
						
							|  |  |  |         httpPrefix + '://' + delegatorDomainFull + '/users/' + nickname | 
					
						
							|  |  |  |     newRoleJson = { | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |         'type': 'Delegate', | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |         'actor': actor, | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |         'object': { | 
					
						
							|  |  |  |             'type': 'Role', | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |             'actor': delegateActor, | 
					
						
							| 
									
										
										
										
											2019-07-18 16:43:48 +00:00
										 |  |  |             'object': roleStr, | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |             'to': [toUrl], | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |             'cc': [ccUrl] | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |         }, | 
					
						
							|  |  |  |         'to': [toUrl], | 
					
						
							|  |  |  |         'cc': [ccUrl] | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     handle = \ | 
					
						
							|  |  |  |         httpPrefix + '://' + delegatorDomainFull + '/@' + delegatorNickname | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # lookup the inbox for the To handle | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     wfRequest = webfingerHandle(session, handle, httpPrefix, | 
					
						
							|  |  |  |                                 cachedWebfingers, | 
					
						
							|  |  |  |                                 delegatorDomain, projectVersion) | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |     if not wfRequest: | 
					
						
							|  |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |             print('DEBUG: announce webfinger failed for ' + handle) | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |         return 1 | 
					
						
							| 
									
										
										
										
											2020-06-23 10:41:12 +00:00
										 |  |  |     if not isinstance(wfRequest, dict): | 
					
						
							|  |  |  |         print('WARN: Webfinger for ' + handle + ' did not return a dict. ' + | 
					
						
							|  |  |  |               str(wfRequest)) | 
					
						
							|  |  |  |         return 1 | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     postToBox = 'outbox' | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # get the actor inbox for the To handle | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     (inboxUrl, pubKeyId, pubKey, | 
					
						
							|  |  |  |      fromPersonId, sharedInbox, | 
					
						
							|  |  |  |      avatarUrl, displayName) = getPersonBox(baseDir, session, | 
					
						
							|  |  |  |                                             wfRequest, personCache, | 
					
						
							|  |  |  |                                             projectVersion, httpPrefix, | 
					
						
							|  |  |  |                                             delegatorNickname, | 
					
						
							|  |  |  |                                             delegatorDomain, postToBox) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |     if not inboxUrl: | 
					
						
							|  |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |             print('DEBUG: No ' + postToBox + ' was found for ' + handle) | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |         return 3 | 
					
						
							|  |  |  |     if not fromPersonId: | 
					
						
							|  |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |             print('DEBUG: No actor was found for ' + handle) | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  |         return 4 | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     authHeader = createBasicAuthHeader(delegatorNickname, password) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     headers = { | 
					
						
							|  |  |  |         'host': delegatorDomain, | 
					
						
							|  |  |  |         'Content-type': 'application/json', | 
					
						
							| 
									
										
										
										
											2020-03-22 20:36:19 +00:00
										 |  |  |         'Authorization': authHeader | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     postResult = \ | 
					
						
							| 
									
										
										
										
											2020-09-27 19:27:24 +00:00
										 |  |  |         postJson(session, newRoleJson, [], inboxUrl, headers) | 
					
						
							| 
									
										
										
										
											2020-04-04 10:28:58 +00:00
										 |  |  |     if not postResult: | 
					
						
							|  |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: POST announce failed for c2s to '+inboxUrl) | 
					
						
							|  |  |  | #        return 5 | 
					
						
							| 
									
										
										
										
											2019-07-18 15:09:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: c2s POST role success') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return newRoleJson |