From 625e5eb0112a96dd77eedf4a75e361d30db3f831 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Mon, 12 Aug 2019 22:20:47 +0100 Subject: [PATCH] Admin can specify moderators --- daemon.py | 33 +++++++++++++++++++++++++++++++++ roles.py | 31 +++++++++++++++++++++++++++---- webinterface.py | 17 ++++++++++++++++- 3 files changed, 76 insertions(+), 5 deletions(-) diff --git a/daemon.py b/daemon.py index c9c9e3223..4c474f4e8 100644 --- a/daemon.py +++ b/daemon.py @@ -60,7 +60,10 @@ from blocking import outboxUndoBlock from blocking import addBlock from blocking import removeBlock from config import setConfigParam +from config import getConfigParam from roles import outboxDelegate +from roles import setRole +from roles import clearModeratorStatus from skills import outboxSkills from availability import outboxAvailability from webinterface import htmlIndividualPost @@ -2008,6 +2011,36 @@ class PubServer(BaseHTTPRequestHandler): for tagName,tag in actorTags.items(): actorJson['tag'].append(tag) actorChanged=True + 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') + approveFollowers=False if fields.get('approveFollowers'): if fields['approveFollowers']=='on': diff --git a/roles.py b/roles.py index bc92fe1c9..989f93d9b 100644 --- a/roles.py +++ b/roles.py @@ -16,9 +16,30 @@ from session import postJson from utils import getNicknameFromActor from utils import getDomainFromActor -def addModerator(baseDir: str,nickname: str): +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 + """ + directory = os.fsencode(baseDir+'/accounts/') + for f in os.listdir(directory): + filename = os.fsdecode(f) + if filename.endswith(".json") and '@' in filename: + filename=os.path.join(baseDir+'/accounts/', filename) + if '"moderator"' in open(filename).read(): + with open(filename, 'r') as fp: + actorJson=commentjson.load(fp) + if actorJson['roles'].get('instance'): + if 'moderator' in actorJson['roles']['instance']: + actorJson['roles']['instance'].remove('moderator') + with open(filename, 'w') as fp: + commentjson.dump(actorJson, fp, indent=4, sort_keys=False) + +def addModerator(baseDir: str,nickname: str,domain: str) -> None: """Adds a moderator nickname to the file """ + if ':' in domain: + domain=domain.split(':')[0] moderatorsFile=baseDir+'/accounts/moderators.txt' if os.path.isfile(moderatorsFile): # is this nickname already in the file? @@ -33,10 +54,12 @@ def addModerator(baseDir: str,nickname: str): for moderator in lines: moderator=moderator.strip('\n') if len(moderator)>1: - f.write(moderator+'\n') + if os.path.isdir(baseDir+'/accounts/'+moderator+'@'+domain): + f.write(moderator+'\n') else: with open(moderatorsFile, "w+") as f: - f.write(nickname+'\n') + if os.path.isdir(baseDir+'/accounts/'+nickname+'@'+domain): + f.write(nickname+'\n') def removeModerator(baseDir: str,nickname: str): """Removes a moderator nickname from the file @@ -68,7 +91,7 @@ def setRole(baseDir: str,nickname: str,domain: str, \ if role: # add the role if project=='instance' and 'role'=='moderator': - addModerator(baseDir,nickname) + addModerator(baseDir,nickname,domain) if actorJson['roles'].get(project): if role not in actorJson['roles'][project]: actorJson['roles'][project].append(role) diff --git a/webinterface.py b/webinterface.py index 9bd877817..114179a31 100644 --- a/webinterface.py +++ b/webinterface.py @@ -174,6 +174,21 @@ def htmlEditProfile(baseDir: str,path: str,domain: str,port: int) -> str: with open(baseDir+'/epicyon-profile.css', 'r') as cssFile: newPostCSS = cssFile.read() + moderatorsStr='' + adminNickname=getConfigParam(baseDir,'admin') + if path.startswith('/users/'+adminNickname+'/'): + moderators='' + moderatorsFile=baseDir+'/accounts/moderators.txt' + if os.path.isfile(moderatorsFile): + with open(moderatorsFile, "r") as f: + moderators = f.read() + moderatorsStr= \ + '
' \ + ' Moderators
' \ + ' A list of moderator nicknames. One per line.' \ + ' ' \ + '
' + editProfileForm=htmlHeader(newPostCSS) editProfileForm+= \ '
' \ @@ -214,7 +229,7 @@ def htmlEditProfile(baseDir: str,path: str,domain: str,port: int) -> str: '
' \ ' Skills
' \ ' If you want to participate within organizations then you can indicate some skills that you have and approximate proficiency levels. This helps organizers to construct teams with an appropriate combination of skills.'+ \ - skillsStr+ \ + skillsStr+moderatorsStr+ \ '
' \ ' ' \ '
'