def handle_api_sophomorix_teachers(self, http_context): action = http_context.json_body()['action'] if http_context.method == 'POST': schoolname = 'default-school' teachersList = [] with authorize('lm:users:teachers:read'): if action == 'get-all': # TODO: This could run with --user-basic but not all memberOf are filled. Needs verification sophomorixCommand = [ 'sophomorix-query', '--teacher', '--schoolbase', schoolname, '--user-basic', '-jj' ] else: user = http_context.json_body()['user'] sophomorixCommand = [ 'sophomorix-query', '--teacher', '--schoolbase', schoolname, '--user-basic', '-jj', '--sam', user ] teachersCheck = lmn_getSophomorixValue(sophomorixCommand, 'LISTS/USER') if len(teachersCheck) != 0: teachers = lmn_getSophomorixValue(sophomorixCommand, 'USER') for teacher in teachers: teachersList.append(teachers[teacher]) return teachersList else: return ["none"] if http_context.method == 'POST': with authorize('lm:users:teachers:write'): return 0
def handle_api_sophomorix_newfile(self, http_context): # TODO needs update for multischool path = http_context.json_body()['path'] userlist = http_context.json_body()['userlist'] if http_context.method == 'POST': if userlist == 'teachers.csv': with authorize('lm:users:teachers:write'): sophomorixCommand = [ 'sophomorix-newfile', path, '--name', userlist, '-jj' ] result = lmn_getSophomorixValue(sophomorixCommand, 'OUTPUT/0') if result['TYPE'] == "ERROR": return ["ERROR", result['MESSAGE_EN']] if result['TYPE'] == "LOG": return ["LOG", result['LOG']] if userlist == 'students.csv': with authorize('lm:users:students:write'): sophomorixCommand = [ 'sophomorix-newfile', path, '--name', userlist, '-jj' ] result = lmn_getSophomorixValue(sophomorixCommand, 'OUTPUT/0') if result['TYPE'] == "ERROR": return ["ERROR", result['MESSAGE_EN']] if result['TYPE'] == "LOG": return ["LOG", result['LOG']]
def handle_api_users_password(self, http_context): action = http_context.json_body()['action'] users = http_context.json_body()['users'] user = '******'.join([x.strip() for x in users]) # Read Password if action == 'get': sophomorixCommand = [ 'sophomorix-user', '--info', '-jj', '-u', user ] return lmn_getSophomorixValue( sophomorixCommand, '/USERS/' + user + '/sophomorixFirstPassword') if action == 'set-initial': sophomorixCommand = [ 'sophomorix-passwd', '--set-firstpassword', '-jj', '-u', user ] return lmn_getSophomorixValue(sophomorixCommand, 'COMMENT_EN') if action == 'set-random': sophomorixCommand = [ 'sophomorix-passwd', '-u', user, '--random', '8', '-jj' ] return lmn_getSophomorixValue(sophomorixCommand, 'COMMENT_EN') if action == 'set': password = http_context.json_body()['password'] sophomorixCommand = [ 'sophomorix-passwd', '-u', user, '--pass', password, '-jj' ] return lmn_getSophomorixValue(sophomorixCommand, 'COMMENT_EN')
def handle_api_users_schooladmins_create(self, http_context): school = 'default-school' action = http_context.json_body()['action'] users = http_context.json_body()['users'] user = '******'.join([x.strip() for x in users]) if action == 'create': with authorize('lm:users:schooladmins:create'): sophomorixCommand = [ 'sophomorix-admin', '--create-school-admin', user, '--school', school, '--random-passwd-save', '-jj' ] result = lmn_getSophomorixValue(sophomorixCommand, 'OUTPUT/0') if result['TYPE'] == "ERROR": return ["ERROR", result['MESSAGE_EN']] if result['TYPE'] == "LOG": return ["LOG", result['LOG']] # return lmn_getSophomorixValue(sophomorixCommand, 'COMMENT_EN') if action == 'delete': with authorize('lm:users:schooladmins:delete'): sophomorixCommand = ['sophomorix-admin', '--kill', user, '-jj'] result = lmn_getSophomorixValue(sophomorixCommand, 'OUTPUT/0') if result['TYPE'] == "ERROR": return ["ERROR", result['MESSAGE_EN']] if result['TYPE'] == "LOG": return ["LOG", result['LOG']]
def handle_api_sophomorix_globaladmins(self, http_context): action = http_context.json_body()['action'] if http_context.method == 'POST': globaladminsList = [] with authorize('lm:users:globaladmins:read'): if action == 'get-all': sophomorixCommand = [ 'sophomorix-query', '--globaladministrator', '--user-full', '-jj' ] else: user = http_context.json_body()['user'] sophomorixCommand = [ 'sophomorix-query', '--globaladministrator', '--user-full', '-jj', '--sam', user ] globaladminsCheck = lmn_getSophomorixValue( sophomorixCommand, 'LISTS/USER') if len(globaladminsCheck) != 0: globaladmins = lmn_getSophomorixValue( sophomorixCommand, 'USER') for globaladmin in globaladmins: globaladminsList.append(globaladmins[globaladmin]) return globaladminsList else: return ["none"] if http_context.method == 'POST': with authorize('lm:users:globaladmins:write'): return 0
def handle_api_sophomorix_students(self, http_context): action = http_context.json_body()['action'] if http_context.method == 'POST': schoolname = 'default-school' studentsList = [] with authorize('lm:users:students:read'): if action == 'get-all': sophomorixCommand = [ 'sophomorix-query', '--student', '--schoolbase', schoolname, '--user-basic', '-jj' ] else: user = http_context.json_body()['user'] # sophomorixCommand = ['sophomorix-query', '--student', '--schoolbase', schoolname, '--user-full', '-jj', '--sam', user] sophomorixCommand = [ 'sophomorix-query', '--user-full', '-jj', '--sam', user ] studentsCheck = lmn_getSophomorixValue(sophomorixCommand, 'LISTS/USER') if len(studentsCheck) != 0: students = lmn_getSophomorixValue(sophomorixCommand, 'USER') for student in students: # TODO: get a better way to remove Birthay from user detail page students[student]['sophomorixBirthdate'] = 'hidden' studentsList.append(students[student]) return studentsList else: return ["none"]
def handle_api_session_file_trans(self, http_context): senders = http_context.json_body()['senders'] command = http_context.json_body()['command'] receivers = http_context.json_body()['receivers'] files = http_context.json_body()['files'] session = http_context.json_body()['session'] now = strftime("%Y%m%d_%H-%M-%S", gmtime()) with authorize('lmn:session:trans'): if command == 'share': try: for sender in senders: # check if bulkmode (array of usernames) or single user (object containing username) # if first element is not a string if not isinstance(receivers[0], six.string_types): receivers[0]= receivers[0]['sAMAccountName'] receiversCSV = ",".join(receivers) for File in files: sophomorixCommand = ['sophomorix-transfer', '-jj', '--scopy', '--from-user', sender, '--to-user', receiversCSV, '--from-path', 'transfer/'+File, '--to-path', 'transfer/'] returnMessage = lmn_getSophomorixValue(sophomorixCommand, 'OUTPUT/0') except Exception as e: raise Exception('Something went wrong. Error:\n' + str(e)) if command == 'copy': try: for receiver in receivers: #raise Exception('Bad value in LDAP field SophomorixUserPermissions! Python error:\n' + str(senders)) sendersCSV = '' for sender in senders: sendersCSV += sender['sAMAccountName']+',' # if files is All we're automatically in bulk mode if files == "All": sophomorixCommand = ['sophomorix-transfer', '-jj', '--scopy', '--from-user', sendersCSV, '--to-user', receiver, '--from-path', 'transfer', '--to-path', 'transfer/collected/'+now+'-'+session+'/', '--to-path-addon', 'fullinfo', '--no-target-directory'] returnMessage = lmn_getSophomorixValue(sophomorixCommand, 'OUTPUT/0') else: for File in files: sophomorixCommand = ['sophomorix-transfer', '-jj', '--scopy', '--from-user', sendersCSV, '--to-user', receiver, '--from-path', 'transfer/'+File, '--to-path', 'transfer/collected/'+now+'-'+session+'/', '--to-path-addon', 'fullinfo' ] returnMessage = lmn_getSophomorixValue(sophomorixCommand, 'OUTPUT/0') except Exception as e: raise Exception('Something went wrong. Error:\n' + str(e)) if command == 'move': try: for receiver in receivers: sendersCSV = '' for sender in senders: sendersCSV += sender['sAMAccountName']+',' # if files is All we're automatically in bulk mode if files == "All": sophomorixCommand = ['sophomorix-transfer', '-jj', '--move', '--keep-source-directory', '--from-user', sendersCSV, '--to-user', receiver, '--from-path', 'transfer', '--to-path', 'transfer/collected/'+now+'-'+session+'/', '--to-path-addon', 'fullinfo', '--no-target-directory'] returnMessage = lmn_getSophomorixValue(sophomorixCommand, 'OUTPUT/0') else: for File in files: sophomorixCommand = ['sophomorix-transfer', '-jj', '--move', '--from-user', sendersCSV, '--to-user', receiver, '--from-path', 'transfer/'+File, '--to-path', 'transfer/collected/'+now+'-'+session+'/', '--to-path-addon', 'fullinfo' ] returnMessage = lmn_getSophomorixValue(sophomorixCommand, 'OUTPUT/0') except Exception as e: raise Exception('Something went wrong. Error:\n' + str(e)) if returnMessage['TYPE'] == "ERROR": return returnMessage['TYPE']['LOG'] return returnMessage['TYPE'], returnMessage['LOG'] return returnMessage['TYPE']['LOG']
def handle_api_search_project(self, http_context): if http_context.method == 'POST': # Problem with unicode Inès --> In\xe8s (py) --> In\ufffds (replace) # Should be Inès --> Ines ( sophomorix supports this ) # login = http_context.json_body()['login'].decode('utf-8', 'replace') login = http_context.json_body()['login'] type = http_context.json_body()['type'] resultArray = [] try: if type == 'user': sophomorixCommand = [ 'sophomorix-query', '--anyname', login + '*', '-jj' ] result = lmn_getSophomorixValue(sophomorixCommand, 'USER') elif type == 'usergroup': sophomorixCommand = [ 'sophomorix-query', '--sam', login + '*', '--group-members', '-jj' ] result = lmn_getSophomorixValue(sophomorixCommand, 'MEMBERS') if len(result) != 1: return [] result = result[login] elif type == 'group': sophomorixCommand = [ 'sophomorix-query', '--anyname', login + '*', '-jj' ] return lmn_getSophomorixValue(sophomorixCommand, 'LISTS/GROUP') for _, details in result.items(): resultArray.append({ 'label': details['sophomorixAdminClass'] + " " + details['sn'] + " " + details['givenName'], 'sn': details['sn'], 'givenName': details['givenName'], 'login': details['sAMAccountName'], 'sophomorixAdminClass': details['sophomorixAdminClass'], }) except: # Ignore SophomorixValue errors pass return resultArray
def handle_api_class_quotas(self, http_context): ## Get quotas for projects and classes if http_context.method == 'GET': groups = {'adminclass': {}, 'project': {}} shares = ['linuxmuster-global', 'default-school'] sophomorixCommand = ['sophomorix-class', '-i', '-jj'] result = lmn_getSophomorixValue(sophomorixCommand, 'GROUPS') for group, details in result.items(): if 'sophomorixType' in details.keys(): ## Class if details['sophomorixType'] == 'adminclass': details['QUOTA'] = {} details['QUOTA']['mailquota'] = { 'value': 0 if details['sophomorixMailQuota'].startswith('---') else int( details['sophomorixMailQuota'].split(':')[0]) } for line in details['sophomorixQuota']: share, value, comment, _ = line.split(':') details['QUOTA'][share] = { 'value': int(value) if value != '---' else 0, 'comment': comment } for share in shares: if share not in details['QUOTA'].keys(): details['QUOTA'][share] = { 'value': 0, 'comment': '' } groups[details['sophomorixType']][group] = details ## Project elif details['sophomorixType'] == 'project': details['QUOTA'] = {} details['QUOTA']['mailquota'] = { 'value': 0 if details['sophomorixAddMailQuota'].startswith('---') else int(details['sophomorixAddMailQuota'].split( ':')[0]) } for line in details['sophomorixAddQuota']: share, value, comment, _ = line.split(':') details['QUOTA'][share] = { 'value': int(value) if value != '---' else 0, 'Comment': comment } for share in shares: if share not in details['QUOTA'].keys(): details['QUOTA'][share] = { 'value': 0, 'Comment': '' } groups[details['sophomorixType']][group] = details return groups
def handle_api_ldap_search(self, http_context): if http_context.method == 'POST': # Problem with unicode Inès --> In\xe8s (py) --> In\ufffds (replace) # Should be Inès --> Ines ( sophomorix supports this ) # login = http_context.json_body()['login'].decode('utf-8', 'replace') login = http_context.json_body()['login'] role = http_context.json_body()['role'] ## --teacher limit the query only to teachers if role: role = '--' + role resultArray = [] try: sophomorixCommand = [ 'sophomorix-query', '--anyname', login + '*', role, '-jj' ] result = lmn_getSophomorixValue(sophomorixCommand, 'USER') for user, details in result.items(): resultArray.append({ 'label': details['sn'] + " " + details['givenName'] + " (" + user + ")", 'login': details['sAMAccountName'], 'role': details['sophomorixRole'], 'displayName': details['sn'] + " " + details['givenName'] }) except: # Ignore SophomorixValue errors pass return resultArray
def handle_api_quota(self, http_context): if http_context.method == 'POST': user = self.context.identity if user != 'root': sophomorixCommand = [ 'sophomorix-query', '--sam', user, '--user-full', '--quota-usage', '-jj' ] jsonpath = 'USER/' + user + '/QUOTA_USAGE_BY_SHARE/linuxmuster-global' result = lmn_getSophomorixValue(sophomorixCommand, jsonpath) if result['HARD_LIMIT_MiB'] == 'NO LIMIT': return { 'used': result['USED_MiB'], 'free': 'Unlimited', 'total': 'Unlimited' } else: return { 'used': result['USED_MiB'], 'free': result['HARD_LIMIT_MiB'] - result['USED_MiB'], 'total': result['HARD_LIMIT_MiB'] } else: return {'used': 0, 'free': 0, 'total': 1}
def handle_api_set_members(self, http_context): """Manages the members of a project""" if http_context.method == 'POST': action = http_context.json_body()['action'] groupname = http_context.json_body()['groupname'] entity = http_context.json_body()['entity'] try: type = http_context.json_body()['type'] except KeyError: type = 'project' possible_actions = [ 'removemembers', 'addmembers', 'addadmins', 'removeadmins', 'addmembergroups', 'removemembergroups', 'addadmingroups', 'removeadmingroups', ] if action in possible_actions: sophomorixCommand = [ 'sophomorix-' + type, '--' + action, entity, '--' + type, groupname, '-jj' ] result = lmn_getSophomorixValue(sophomorixCommand, 'OUTPUT/0') if result['TYPE'] == "ERROR": return result['TYPE'], result['MESSAGE_EN'] return result['TYPE'], result['LOG']
def handle_api_get_user_in_room(self, http_context): if http_context.method == 'POST': school = 'default-school' action = http_context.json_body()['action'] username = http_context.json_body()['username'] with authorize('lm:users:students:read'): if action == 'get-my-room': try: sophomorixCommand = [ 'sophomorix-query', '-jj', '--smbstatus', '--schoolbase', school, '--query-user', username ] response = lmn_getSophomorixValue( sophomorixCommand, '') # remove our own room = response[username]['ROOM'] response.pop(username, None) usersList = [] usersInRoom = {} for user in response: usersList.append(user) usersInRoom = { "usersList": usersList, "room": room, "objects": response } return usersInRoom except Exception: return 0
def handle_api_session_sessions(self, http_context): fileToCheck = http_context.json_body()['path'] if os.path.isfile(fileToCheck): sophomorixCommand = [ 'sophomorix-check', '--analyze-encoding', fileToCheck, '-jj' ] encoding = lmn_getSophomorixValue( sophomorixCommand, 'SUMMARY/0/ANALYZE-ENCODING/ENCODING') return encoding else: return None
def handle_api_ldap_user_search(self, http_context): school = 'default-school' with authorize('lm:users:students:read'): try: sophomorixCommand = ['sophomorix-query', '-jj', '--schoolbase', school, '--student', '--user-basic', '--anyname', '*'+http_context.query['q']+'*'] users = lmn_getSophomorixValue(sophomorixCommand, 'USER', True) except Exception: return 0 userList = [] for user in users: userList.append(users[user]) return userList
def handle_api_quota(self, http_context, user): if http_context.method == 'GET': if user != 'root': sophomorixCommand = [ 'sophomorix-query', '--sam', user, '--user-full', '--quota-usage', '-jj' ] jsonpath = 'USER/' + user return lmn_getSophomorixValue(sophomorixCommand, jsonpath) return {}
def handle_api_create_dir(self, http_context): """Create directory with given path, ignoring errors""" if http_context.method == 'POST': user = http_context.json_body()['user'] filepath = http_context.json_body()['filepath'] subdir = http_context.json_body()['subdir'] try: sophomorixCommand = [ 'sophomorix-transfer', '--from-unix-path', filepath, '--to-user', user, '--subdir', subdir, '-jj' ] return lmn_getSophomorixValue(sophomorixCommand, '', True) except Exception: return 0
def handle_api_ldap_group_search(self, http_context): school = 'default-school' with authorize('lm:users:students:read'): try: sophomorixCommand = ['sophomorix-query', '-jj', '--schoolbase', school, '--class', '--group-members', '--user-full', '--sam', '*'+http_context.query['q']+'*'] schoolClasses = lmn_getSophomorixValue(sophomorixCommand, 'MEMBERS', True) except Exception: return 0 schoolClassList = [] for schoolClass in schoolClasses: schoolClassJson = {} schoolClassJson['sophomorixAdminClass'] = schoolClass schoolClassJson['members'] = schoolClasses[schoolClass] schoolClassList.append(schoolClassJson) return schoolClassList
def handle_api_groupmembership_details(self, http_context): action = http_context.json_body()['action'] if http_context.method == 'POST': # schoolname = 'default-school' with authorize('lmn:groupmemberships:write'): if action == 'get-specified': groupName = http_context.json_body()['groupName'] sophomorixCommand = [ 'sophomorix-query', '--group-members', '--group-full', '--sam', groupName, '-jj' ] groupDetails = lmn_getSophomorixValue( sophomorixCommand, '') if not 'MEMBERS' in groupDetails.keys(): groupDetails['MEMBERS'] = {} return groupDetails
def handle_api_session_file_trans_list(self, http_context): user = http_context.json_body()['user'] # check if user is a string(given by share option) or an object in an array (given by collect option) if not isinstance(user, six.string_types): user = user[0]['sAMAccountName'] subfolderPath = '' if 'subfolderPath' in http_context.json_body(): subfolderPath = http_context.json_body()['subfolderPath'] sophomorixCommand = ['sophomorix-transfer', '-j', '--list-home-dir', user, '--subdir', '/transfer'+subfolderPath] availableFiles = lmn_getSophomorixValue(sophomorixCommand, 'sAMAccountName/'+user) #raise Exception('Bad value in LDAP field SophomorixUserPermissions! Python error:\n' + str(availableFiles)) availableFilesList = [] if availableFiles['COUNT']['files'] == 0 and availableFiles['COUNT']['directories'] == 0: return availableFiles, ['null'] for availableFile in availableFiles['TREE']: availableFilesList.append(availableFile) return availableFiles, availableFilesList
def handle_api_set_group(self, http_context): """Handles join and hide options for a group.""" if http_context.method == 'POST': option = http_context.json_body()['option'] group = http_context.json_body()['group'] groupType = http_context.json_body()['type'] if groupType == "project": sophomorixCommand = [ 'sophomorix-project', option, '--project', group, '-jj' ] else: # Class sophomorixCommand = [ 'sophomorix-class', option, '--class', group, '-jj' ] result = lmn_getSophomorixValue(sophomorixCommand, 'OUTPUT/0') if result['TYPE'] == "ERROR": return result['TYPE'], result['MESSAGE_EN'] return result['TYPE'], result['LOG']
def handle_api_groups(self, http_context): schoolname = 'default-school' username = http_context.json_body()['username'] action = http_context.json_body()['action'] user_details = http_context.json_body()['profil'] isAdmin = "administrator" in user_details['sophomorixRole'] if http_context.method == 'POST': if action == 'list-groups': membershipList = [] usergroups = [] if not isAdmin: # get groups specified user is member of for group in user_details['memberOf']: usergroups.append(group.split(',')[0].split('=')[1]) # get all available classes and projects sophomorixCommand = [ 'sophomorix-query', '--class', '--project', '--schoolbase', schoolname, '--group-full', '-jj' ] groups = lmn_getSophomorixValue(sophomorixCommand, '') # get all available groups TODO # build membershipList with membership status for group in groups['LISTS']['GROUP']: membershipDict = {} groupDetails = groups['GROUP'][group] if group in usergroups or isAdmin or groupDetails[ 'sophomorixHidden'] == "FALSE": membershipDict['groupname'] = group membershipDict[ 'membership'] = group in usergroups or isAdmin membershipDict['admin'] = username in groupDetails[ 'sophomorixAdmins'] or isAdmin membershipDict['joinable'] = groupDetails[ 'sophomorixJoinable'] membershipDict['DN'] = groupDetails['DN'] # Project name always starts with p_, but not classname if group[:2] == "p_": membershipDict['type'] = 'project' membershipDict['typename'] = 'Project' else: membershipDict['type'] = 'schoolclass' membershipDict['typename'] = 'Class' membershipList.append(membershipDict) #get printers sophomorixCommand = [ 'sophomorix-query', '--printergroup', '--schoolbase', schoolname, '-jj' ] printergroups = lmn_getSophomorixValue(sophomorixCommand, 'LISTS/GROUP') for printergroup in printergroups: if printergroup in usergroups or isAdmin: membershipList.append({ 'type': 'printergroup', 'typename': 'Printer', 'groupname': printergroup, 'membership': True }) else: membershipList.append({ 'type': 'printergroup', 'typename': 'Printer', 'groupname': printergroup, 'membership': False }) return membershipList, isAdmin, user_details if action == 'kill-project': project = http_context.json_body()['project'] sophomorixCommand = [ 'sophomorix-project', '-i', '-p', project, '-jj' ] groupAdmins = lmn_getSophomorixValue( sophomorixCommand, 'GROUPS/' + project + '/sophomorixAdmins') if username in groupAdmins or username == 'global-admin': sophomorixCommand = [ 'sophomorix-project', '--kill', '-p', project, '-jj' ] result = lmn_getSophomorixValue(sophomorixCommand, 'OUTPUT/0') if result['TYPE'] == "ERROR": return result['TYPE']['LOG'] # Try to return last result to frontend return result['TYPE'], result['LOG'] # TODO: This should be done by sophomorix return ['ERROR', 'Permission Denied'] sophomorixCommand = [ 'sophomorix-project', '--admins', username, '--create', '-p', project, '-jj' ] result = lmn_getSophomorixValue(sophomorixCommand, 'OUTPUT/0') if result['TYPE'] == "ERROR": return result['TYPE']['LOG'] return result['TYPE'], result['LOG'] if action == 'create-project': ## Projectname must be in lowercase to avoid conflicts project = http_context.json_body()['project'].lower() sophomorixCommand = [ 'sophomorix-project', '--admins', username, '--create', '-p', project, '-jj' ] result = lmn_getSophomorixValue(sophomorixCommand, 'OUTPUT/0') if result['TYPE'] == "ERROR": return result['TYPE']['LOG'] return result['TYPE'], result['LOG']
def handle_api_users_check(self, http_context): sophomorixCommand = ['sophomorix-check', '-jj'] results = lmn_getSophomorixValue(sophomorixCommand, '') return results
def handle_api_users_print(self, http_context): school = 'default-school' if http_context.method == 'GET': sophomorixCommand = [ 'sophomorix-print', '--school', school, '--info', '-jj' ] with authorize('lm:users:students:read'): # classes = lmn_getSophomorixValue(sophomorixCommand, 'LIST_BY_sophomorixSchoolname_sophomorixAdminClass/'+school) # Check if there are any classes if not return empty list classes_raw = lmn_getSophomorixValue(sophomorixCommand, '') if 'LIST_BY_sophomorixSchoolname_sophomorixAdminClass' not in classes_raw: classes = [] else: classes = classes_raw[ 'LIST_BY_sophomorixSchoolname_sophomorixAdminClass'][ school] if lmn_checkPermission('lm:users:teachers:read'): # append empty element. This references to all users classes.append('') else: classes.remove('teachers') return classes if http_context.method == 'POST': user = http_context.json_body()['user'] one_per_page = http_context.json_body()['one_per_page'] pdflatex = http_context.json_body()['pdflatex'] schoolclass = http_context.json_body()['schoolclass'] sophomorixCommand = [ 'sophomorix-print', '--school', school, '--caller', str(user) ] if one_per_page: sophomorixCommand.extend(['--one-per-page']) if pdflatex: sophomorixCommand.extend(['--command']) sophomorixCommand.extend(['pdflatex']) if schoolclass: sophomorixCommand.extend(['--class', schoolclass]) # sophomorix-print needs the json parameter at the very end sophomorixCommand.extend(['-jj']) # check permissions if not schoolclass: # double check if user is allowed to print all passwords with authorize('lm:users:teachers:read'): pass # double check if user is allowed to print teacher passwords if schoolclass == 'teachers': with authorize('lm:users:teachers:read'): pass # generate real shell environment for sophomorix print shell_env = { 'TERM': 'xterm', 'SHELL': '/bin/bash', 'PATH': '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', 'HOME': '/root', '_': '/usr/bin/python2' } subprocess.check_call(sophomorixCommand, shell=False, env=shell_env) return
def handle_api_session_sessions(self, http_context): action = http_context.json_body()['action'] if action == 'get-sessions': supervisor = http_context.json_body()['username'] with authorize('lm:users:students:read'): try: sophomorixCommand = ['sophomorix-session', '-i', '-jj', '--supervisor', supervisor] sessions = lmn_getSophomorixValue(sophomorixCommand, '') # Most likeley key error 'cause no sessions for this user exist except Exception as e: raise Exception('Bad value in LDAP field SophomorixUserPermissions! Python error:\n' + str(e)) return 0 sessionsList = [] if supervisor not in sessions['SUPERVISOR_LIST']: sessionJson = {} sessionJson['SESSIONCOUNT'] = 0 sessionsList.append(sessionJson) return sessionsList for session in sessions['SUPERVISOR'][supervisor]['sophomorixSessions']: sessionJson = {} sessionJson['ID'] = session sessionJson['COMMENT'] = sessions['SUPERVISOR'][supervisor]['sophomorixSessions'][session]['COMMENT'] if 'PARTICIPANT_COUNT' not in sessions['SUPERVISOR'][supervisor]['sophomorixSessions'][session]: sessionJson['PARTICIPANT_COUNT'] = 0 else: sessionJson['PARTICIPANT_COUNT'] = sessions['SUPERVISOR'][supervisor]['sophomorixSessions'][session]['PARTICIPANT_COUNT'] sessionsList.append(sessionJson) return sessionsList if action == 'get-participants': participantList = [] supervisor = http_context.json_body()['username'] session = http_context.json_body()['session'] with authorize('lm:users:students:read'): try: sophomorixCommand = ['sophomorix-session', '-i', '-jj'] participants = lmn_getSophomorixValue(sophomorixCommand, 'ID/'+session+'/PARTICIPANTS', True) i = 0 for participant in participants: participantList.append(participants[participant]) participantList[i]['sAMAccountName'] = participant #if participant.endswith('-exam'): # participantList[i]['sAMAccountname-basename'] = participant.replace('-exam', '') #else: # participantList[i]['sAMAccountname-basename'] = participant participantList[i]['changed'] = 'FALSE' participantList[i]['exammode-changed'] = 'FALSE' for key in participantList[i]: if participantList[i][key] == 'TRUE': participantList[i][key] = True if participantList[i][key] == 'FALSE': participantList[i][key] = False i = i + 1 except Exception: participantList = 'empty' return participantList if action == 'kill-sessions': session = http_context.json_body()['session'] with authorize('lm:users:students:read'): sophomorixCommand = ['sophomorix-session', '-j', '--session', session, '--kill'] result = lmn_getSophomorixValue(sophomorixCommand, 'OUTPUT/0/LOG') return result if action == 'rename-session': session = http_context.json_body()['session'] comment = http_context.json_body()['comment'] with authorize('lm:users:students:read'): sophomorixCommand = ['sophomorix-session', '-j', '--session', session, '--comment', comment] result = lmn_getSophomorixValue(sophomorixCommand, 'OUTPUT/0/LOG') return result if action == 'new-session': supervisor = http_context.json_body()['username'] comment = http_context.json_body()['comment'] with authorize('lm:users:students:read'): sophomorixCommand = ['sophomorix-session', '--create', '--supervisor', supervisor, '-j', '--comment', comment] result = lmn_getSophomorixValue(sophomorixCommand, 'OUTPUT/0/LOG') return result # TODO: Removed remove block in future release #if action == 'change-exam-supervisor': # supervisor = http_context.json_body()['supervisor'] # participant = http_context.json_body()['participant'] # comment = http_context.json_body()['comment'] # with authorize('lm:users:students:read'): # try: # sophomorixCommand = ['sophomorix-exam-mode', '--unset', '--subdir', session, '-j', '--participants', participant] # result = lmn_getSophomorixValue(sophomorixCommand, 'COMMENT_EN') # except Exception as e: # raise Exception('Error:\n' + str(e)) # try: # sophomorixCommand = ['sophomorix-exam-mode', '--set', '--supervisor', supervisor, '-j', '--participants', participant] # result = lmn_getSophomorixValue(sophomorixCommand, 'COMMENT_EN') # except Exception as e: # raise Exception('Error:\n' + str(e)) if action == 'end-exam': supervisor = http_context.json_body()['supervisor'] participant = http_context.json_body()['participant'] sessionName = http_context.json_body()['sessionName'] now = strftime("%Y%m%d_%H-%M-%S", gmtime()) #raise Exception('Bad value in LDAP field SophomorixUserPermissions! Python error:\n' + str(http_context.json_body())) with authorize('lm:users:students:read'): try: sophomorixCommand = ['sophomorix-exam-mode', '--unset', '--subdir', 'transfer/collected/'+now+'-'+sessionName+'-ended-by-'+supervisor+'/exam', '-j', '--participants', participant] result = lmn_getSophomorixValue(sophomorixCommand, 'COMMENT_EN') except Exception as e: raise Exception('Error:\n' + str(e)) if action == 'save-session': def checkIfUserInManagementGroup(participant, participantBasename, managementgroup, managementList, noManagementList): try: boolean = participant[managementgroup] if (boolean is True) or (boolean == 'TRUE'): managementList.append(participantBasename) else: noManagementList.append(participantBasename) except KeyError: noManagementList.append(participantBasename) pass return 0 session = http_context.json_body()['session'] sessionName = http_context.json_body()['sessionName'] supervisor = http_context.json_body()['username'] participants = http_context.json_body()['participants'] participantsList = [] now = strftime("%Y%m%d_%H-%M-%S", gmtime()) examModeList, noExamModeList, wifiList, noWifiList, internetList, noInternetList, intranetList, noIntranetList, webfilterList, noWebfilterList, printingList, noPrintingList = [], [], [], [], [], [], [], [], [], [], [], [] # Remove -exam in username to keep username as it is insead of saving -exam usernames in session for participant in participants: if participant['sAMAccountName'].endswith('-exam'): participantBasename = participant['sAMAccountName'].replace('-exam', '') else: participantBasename = str(participant['sAMAccountName']) #participant['sAMAccountName'] # Fill lists from WebUI Output -> Create csv of session members # This will executed on every save participantsList.append(participantBasename) # Only check for exammode if this value was changed in WEBUI if participant['exammode-changed'] is True: checkIfUserInManagementGroup(participant, participantBasename, 'exammode_boolean', examModeList, noExamModeList) # Only check for managementgroups if this value was changed in WEBUI if participant['changed'] is True: checkIfUserInManagementGroup(participant, participant['sAMAccountName'], 'group_wifiaccess', wifiList, noWifiList) checkIfUserInManagementGroup(participant, participant['sAMAccountName'], 'group_internetaccess', internetList, noInternetList) checkIfUserInManagementGroup(participant, participant['sAMAccountName'], 'group_intranetaccess', intranetList, noIntranetList) checkIfUserInManagementGroup(participant, participant['sAMAccountName'], 'group_webfilter', webfilterList, noWebfilterList) checkIfUserInManagementGroup(participant, participant['sAMAccountName'], 'group_printing', printingList, noPrintingList) #i = i + 1 # Create CSV lists we need for sophomorix participantsCSV = ",".join(participantsList) examModeListCSV = ",".join(examModeList) noExamModeListCSV = ",".join(noExamModeList) wifiListCSV = ",".join(wifiList) noWifiListCSV = ",".join(noWifiList) internetListCSV = ",".join(internetList) noInternetListCSV = ",".join(noInternetList) intranetListCSV = ",".join(intranetList) noIntranetListCSV = ",".join(noIntranetList) webfilterListCSV = ",".join(webfilterList) noWebfilterListCSV = ",".join(noWebfilterList) printingListCSV = ",".join(printingList) noPrintingListCSV = ",".join(noPrintingList) # Set managementgroups try: sophomorixCommand = ['sophomorix-managementgroup', '--wifi', wifiListCSV, '--nowifi', noWifiListCSV, '--internet', internetListCSV, '--nointernet', noInternetListCSV, '--intranet', intranetListCSV, '--nointranet', noIntranetListCSV, '--webfilter', webfilterListCSV, '--nowebfilter', noWebfilterListCSV, '--printing', printingListCSV, '--noprinting', noPrintingListCSV, '-jj'] result = lmn_getSophomorixValue(sophomorixCommand, 'OUTPUT/0/LOG') except Exception as e: raise Exception('Error:\n' + str('sophomorix-managementgroup \ --wifi "' + wifiListCSV + '" --nowifi "' + noWifiListCSV + '" --internet "' + internetListCSV + '" --nointernet "' + noInternetListCSV + '" --intranet "' + intranetListCSV + '" --nointranet "' + noIntranetListCSV + '" --webfilter "' + webfilterListCSV + '" --nowebfilter "' + noWebfilterListCSV + '" --printing "' + printingListCSV + '" --noprinting "' + noPrintingListCSV + '" -jj ') + "\n Error was: " + str(e)) # Save session members try: sophomorixCommand = ['sophomorix-session', '--session', session, '-j', '--participants', participantsCSV] result = lmn_getSophomorixValue(sophomorixCommand, 'OUTPUT/0/LOG') except Exception: raise Exception('Error:\n' + str('sophomorix-session --session ' + session + ' -j --participants ' + participantsCSV)) # Put chosen members in exam mode try: if examModeListCSV != "": sophomorixCommand = ['sophomorix-exam-mode', '--set', '--supervisor', supervisor, '-j', '--participants', examModeListCSV] result = lmn_getSophomorixValue(sophomorixCommand, 'COMMENT_EN') except Exception: raise Exception('Error:\n' + str('sophomorix-exam-mode --set --supervisor ' + supervisor + ' -j --participants ' + examModeListCSV)) # Remove chosen members from exam mode try: if noExamModeListCSV != "": sophomorixCommand = ['sophomorix-exam-mode', '--unset', '--subdir', 'transfer/collected/'+now+'-'+sessionName+'/exam', '-j', '--participants', noExamModeListCSV] result = lmn_getSophomorixValue(sophomorixCommand, 'COMMENT_EN') except Exception: raise Exception('Error:\n' + str('sophomorix-exam-mode --unset --subdir ' + session + ' -j --participants ' + noExamModeListCSV)) return result if http_context.method == 'POST': with authorize('lm:users:students:write'): return 0
def handle_api_quotas(self, http_context): school = 'default-school' settings_path = '/etc/linuxmuster/sophomorix/' + school + '/school.conf' quota_types = { 'quota_default_global': 'linuxmuster-global', 'quota_default_school': 'default-school', } if http_context.method == 'GET': ## Parse csv config file config = ConfigParser() config.read(settings_path) settings = {} for section in config.sections(): settings[section] = {} for (key, val) in config.items(section): if 'quota' in key: if val.isdigit(): val = int(val) if val == 'no': val = False if val == 'yes': val = True settings[section][key] = val ## Get list of non default quota user, others get the default value ## Teachers and students are mixed in the same dict non_default = { 'teacher': { 'list': [] }, 'student': { 'list': [] }, 'schooladministrator': { 'list': [] } } sophomorixCommand = ['sophomorix-quota', '-i', '-jj'] result = lmn_getSophomorixValue( sophomorixCommand, 'NONDEFAULT_QUOTA/' + school + '/USER') for login, values in result.items(): role = values['sophomorixRole'] non_default[role][login] = values non_default[role]['list'].append({ 'sn': values['sn'], 'login': login, 'givenname': values['givenName'] }) # Normal shares if 'QUOTA' in values.keys(): for tag, share in quota_types.items(): if share not in values['QUOTA'] or values['QUOTA'][ share]['VALUE'] == "---": values['QUOTA'][tag] = settings['role.' + role][tag] else: values['QUOTA'][tag] = int( values['QUOTA'][share]['VALUE']) del values['QUOTA'][share] else: values['QUOTA'] = {} for tag, _ in quota_types.items(): values['QUOTA'][tag] = settings['role.' + role][tag] # Mailquota if 'MAILQUOTA' in values.keys(): values['QUOTA']['mailquota_default'] = int( values['MAILQUOTA']['VALUE']) else: values['QUOTA']['mailquota_default'] = settings[ 'role.' + role]['mailquota_default'] # Cloudquota values['QUOTA']['cloudquota_percentage'] = settings[ 'role.' + role]['cloudquota_percentage'] return [non_default, settings]
def handle_api_save_quotas(self, http_context): quota_types = { 'quota_default_global': 'linuxmuster-global', 'quota_default_school': 'default-school', } if http_context.method == 'POST': ## Update quota per user, but not applied yet ## Not possible to factorise the command for many users for _, userDict in http_context.json_body()['users'].items(): for _, values in userDict.items(): if values['quota'] == 'mailquota_default': sophomorixCommand = [ 'sophomorix-user', '--mailquota', '%s' % (values['value']), '-u', values['login'], '-jj' ] else: sophomorixCommand = [ 'sophomorix-user', '--quota', '%s:%s:---' % (quota_types[values['quota']], values['value']), '-u', values['login'], '-jj' ] lmn_getSophomorixValue(sophomorixCommand, '') ## Update quota per class, but not applied yet for _, grpDict in http_context.json_body( )['groups']['adminclass'].items(): if grpDict['quota'] == 'mailquota': sophomorixCommand = [ 'sophomorix-class', '-c', grpDict['group'], '--mailquota', '%s:' % grpDict['value'], '-jj' ] else: sophomorixCommand = [ 'sophomorix-class', '-c', grpDict['group'], '--quota', '%s:%s:---' % (grpDict['quota'], grpDict['value']), '-jj' ] lmn_getSophomorixValue(sophomorixCommand, '') ## Update quota per project, but not applied yet for _, grpDict in http_context.json_body( )['groups']['project'].items(): if grpDict['quota'] == 'mailquota': sophomorixCommand = [ 'sophomorix-project', '-p', grpDict['group'], '--addmailquota', '%s:' % grpDict['value'], '-jj' ] else: sophomorixCommand = [ 'sophomorix-project', '-p', grpDict['group'], '--addquota', '%s:%s:---' % (grpDict['quota'], grpDict['value']), '-jj' ] lmn_getSophomorixValue(sophomorixCommand, '')