diff --git a/daemon.py b/daemon.py index c9c9e322..4c474f4e 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 bc92fe1c..989f93d9 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 9bd87781..114179a3 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+ \ '
' \ ' ' \ '
'