class MembersController(BaseController): def __init__(self): super(MembersController, self).__init__() self.lmf = LdapModelFactory() @BaseController.needAdmin def __before__(self): super(MembersController, self).__before__() def _sidebar(self): super(MembersController, self)._sidebar() c.actions.append({'name' : _('Show all members'), 'args' : {'controller' : 'members', 'action' : 'showAllMembers'}}) c.actions.append({'name' : _('Add member'), 'args' : {'controller' : 'members', 'action' : 'addMember'}}) c.actions.append({'name' : _('Active members'), 'args' : {'controller' : 'members', 'action' : 'showActiveMembers'}}) c.actions.append({'name' : _('Former members'), 'args' : {'controller' : 'members', 'action' : 'showFormerMembers'}}) c.actions.append({'name' : _('Groups'), 'args' : {'controller' : 'groups', 'action' : 'index'}}) def index(self): return self.showAllMembers() @BaseController.needAdmin def addMember(self): c.heading = _('Add member') c.mode = 'add' c.groups = [] return render('/members/editMember.mako') def editMember(self): if (not 'member_id' in request.params): redirect(url(controller='members', action='showAllMembers')) try: member = self.lmf.getUser(request.params['member_id']) c.heading = _('Edit member') c.mode = 'edit' c.member = member if member.fullMember: c.member.full_member = 'checked' if member.lockedMember: c.member.locked_member = 'checked' return render('/members/editMember.mako') except LookupError: print 'No such user !' return 'ERROR 4x0' def checkMember(f): def new_f(self): # @TODO request.params may contain multiple values per key... test & fix if (not 'member_id' in request.params): redirect(url(controller='members', action='showAllMembers')) else: formok = True errors = [] try: ParamChecker.checkMode('mode', values=('add', 'edit')) except InvalidParameterFormat as ipf: formok = False errors.append(ipf.message) m = Member() for v in m.str_vars: setattr(m, v, request.params.get(v, '')) m.uid = request.params['member_id'] try: m.check() except InvalidParameterFormat as ipf: formok = False errors += ipf.message if request.params['mode'] == 'add' or not request.params.get('userPassword', '') == '': try: ParamChecker.checkPassword('userPassword', 'userPassword2') except InvalidParameterFormat as ipf: formok = False errors.append(ipf.message) if not formok: session['errors'] = errors session['reqparams'] = {} # @TODO request.params may contain multiple values per key... test & fix for k in request.params.iterkeys(): if (k == 'full_member' or k == 'locked_member') and request.params[k] == 'on': session['reqparams'][k] = 'checked' else: session['reqparams'][k] = request.params[k] session.save() if request.params['mode'] == 'add': redirect(url(controller='members', action='addMember')) else: redirect(url(controller='members', action='editMember', member_id=request.params['member_id'])) return f(self) return new_f @checkMember @restrict('POST') def doEditMember(self): try: if request.params['mode'] == 'edit': member = self.lmf.getUser(request.params['member_id']) else: member = Member() member.uid = request.params['member_id'] for v in member.str_vars: if v in request.params: setattr(member, v, request.params.get(v).lstrip(' ').rstrip(' ')) # @TODO review: for now we don't allow custom GIDs member.gidNumber = '100' member.cn = member.givenName + ' ' + member.sn member.homeDirectory = '/home/' + request.params['member_id'] if not request.params.get('userPassword', '') == '' and request.params['userPassword'] == request.params['userPassword2']: member.setPassword(request.params['userPassword']) if 'full_member' in request.params: member.fullMember = True else: member.fullMember = False if 'locked_member' in request.params: member.lockedMember = True else: member.lockedMember = False if 'spaceKey' in request.params: member.spaceKey = True else: member.spaceKey = False if 'npoMember' in request.params: member.npoMember = True else: member.npoMember = False if 'isMinor' in request.params: member.isMinor = True else: member.isMinor = False member.nationality = member.nationality.upper() if request.params['mode'] == 'edit': self.lmf.saveMember(member) else: self.lmf.saveMember(member) session['flash'] = _('Member details successfully edited') session.save() redirect(url(controller='members', action='editMember', member_id=request.params['member_id'])) except LookupError: print 'No such user !' # @TODO make much more noise ! redirect(url(controller='members', action='showAllMembers')) def showAllMembers(self, _filter='active'): try: c.heading = _('All members') members = self.lmf.getUsers() c.members = [] # make sure to clean out some vars for m in members: m.sambaNTPassword = '******' m.userPassword = '******' if _filter == 'active' and not m.lockedMember: c.members.append(m) elif _filter == 'former' and m.lockedMember: c.members.append(m) elif _filter == 'all': c.members.append(m) return render('/members/viewAll.mako') except LookupError as e: import sys, traceback traceback.print_exc(file=sys.stdout) print 'Lookup error!' print e pass except NoResultFound: print 'No such sql user !' return 'ERROR 4x0' def exportList(self): try: members = self.lmf.getUsers() c.members = [] # make sure to clean out some vars for m in members: m.sambaNTPassword = '******' m.userPassword = '******' if not m.lockedMember: c.members.append(m) if 'listType' in request.params and request.params['listType'] == 'RCSL': response.content_type = 'text/plain' return render('/members/exportRCSLCSV.mako') else: response.content_type = 'text/plain' return render('/members/exportCSV.mako') except LookupError as e: print 'Lookup error!' print e pass return 'ERROR 4x0' def showActiveMembers(self): return self.showAllMembers(_filter='active') def showFormerMembers(self): return self.showAllMembers(_filter='former') def validateMember(self): if (not 'member_id' in request.params): redirect(url(controller='members', action='showAllMembers')) try: member = self.lmf.getUser(request.params['member_id']) if member.validate: tm = Session.query(TmpMember).filter(TmpMember.id == member.uidNumber).first() member.cn = u'{0} {1}'.format(tm.gn, tm.sn) member.givenName = tm.gn member.sn = tm.sn member.homePostalAddress = tm.homePostalAddress member.homePhone = tm.phone member.mobile = tm.mobile member.mail = tm.mail member.xmppID = tm.xmppID self.lmf.saveMember(member) Session.delete(tm) Session.commit() self.postValidationMail(request.params['member_id'], member.mail, validated=True) else: session['flash'] = _('Nothing to validate!') except LookupError: session['flash'] = _('Member validation failed!') session.save() redirect(url(controller='members', action='showAllMembers')) def rejectValidation(self): if (not 'member_id' in request.params): redirect(url(controller='members', action='showAllMembers')) try: member = self.lmf.getUser(request.params['member_id']) if member.validate: tm = Session.query(TmpMember).filter(TmpMember.id == member.uidNumber).first() mail = tm.mail Session.delete(tm) Session.commit() self.postValidationMail(request.params['member_id'], mail, validated=False) else: session['flash'] = _('Nothing to reject!') except LookupError: session['flash'] = _('Failed to reject validation!') session.save() redirect(url(controller='members', action='showAllMembers')) def postValidationMail(self, member_id, member_mail, validated=True): if validated: validation_string = 'validated' else: validation_string = 'rejected' # office e-mail body = 'Hi,\n' body += session['identity'] + ' just ' + validation_string + ' the profile changes of the following member:\n' body += member_id + '\n\n' body += 'regards,\nMeMaTool' to = '*****@*****.**' subject = config.get('mematool.name_prefix') + ' mematool - request for validation - ' + validation_string self.sendMail(to, subject, body) # user e-mail body = 'Hi,\n' body += 'The office has just ' + validation_string + ' your profile changes.\n' body += 'If you don\'t agree with this decision, please contact them for more information.\n\n' body += 'regards,\nMeMaTool on behalf of the office' self.sendMail(member_mail, subject, body) def viewDiff(self): if not 'member_id' in request.params: redirect(url(controller='members', action='showAllMembers')) try: member = self.lmf.getUser(request.params['member_id']) if member.validate: c.heading = _('View diff') c.member = member tmpmember = Session.query(TmpMember).filter(TmpMember.id == member.uidNumber).first() c.tmpmember = tmpmember return render('/members/viewDiff.mako') except LookupError: print 'No such user !' return 'ERROR 4x0' @BaseController.needAdmin def deleteUser(self): try: member_id = request.params.get('member_id') self.lmf.deleteUser(member_id) aliases = self.lmf.getMaildropList(member_id) errors = '' for dn, attr in aliases.items(): if errors == '': errors = 'Could not auto-delete the following aliases:' m = re.match(r'^mail=([^,]+),', dn) if m: alias = m.group(1) url_ = url(controller='mails', action='editAlias', alias=alias) errors += '\n<br/><a href="{0}" target="_blank">{1}</a>'.format(url_, alias) if not errors == '': if not 'errors' in session: session['errors'] = [] session['errors'].append(literal(errors)) session['flash'] = _('User successfully deleted') session.save() except LookupError: session['flash'] = _('Failed to delete user') session.save() # @TODO make much more noise ! redirect(url(controller='members', action='showAllMembers'))
class ProfileController(BaseController): def __init__(self): super(ProfileController, self).__init__() self.lmf = LdapModelFactory() def __before__(self): super(ProfileController, self).__before__() def _sidebar(self): super(ProfileController, self)._sidebar() c.actions.append({'name' : _('Preferences'), 'args' : {'controller' : 'preferences', 'action' : 'edit'}}) c.actions.append({'name' : _('Payments'), 'args' : {'controller' : 'payments', 'action' : 'listPayments', 'member_id' : session['identity']}}) def index(self): return self.edit() def edit(self): c.heading = _('Edit profile') c.formDisabled = '' try: member = self.lmf.getUser(session['identity']) if member.validate: tm = Session.query(TmpMember).filter(TmpMember.id == member.uidNumber).first() member.cn = u'{0} {1}'.format(tm.gn, tm.sn) member.givenName = tm.gn member.sn = tm.sn member.homePostalAddress = tm.homePostalAddress member.homePhone = tm.phone member.mobile = tm.mobile member.mail = tm.mail member.xmppID = tm.xmppID c.formDisabled = 'disabled' c.member = member c.member.avatarUrl = self.avatarUrl(member.uid, size=180) c.groups = self.lmf.getUserGroupList(session['identity']) if member.fullMember: c.member.full_member = True else: c.member.full_member = False if member.lockedMember: c.member.locked_member = True else: c.member.locked_member = False return render('/profile/edit.mako') except LookupError: print 'Edit :: No such user !' return 'ERROR 4x0' def checkMember(f): def new_f(self): # @TODO request.params may contain multiple values per key... test & fix formok = True errors = [] m = self.lmf.getUser(session['identity']) for v in m.str_vars: if v in request.params: setattr(m, v, request.params.get(v, '')) try: m.check() except InvalidParameterFormat as ipf: formok = False errors += ipf.message if not request.params.get('userPassword', '') == '' and request.params['userPassword'] == request.params['userPassword2']: try: ParamChecker.checkPassword('userPassword', 'userPassword2') except InvalidParameterFormat as ipf: formok = False errors.append(ipf.message) if not formok: session['errors'] = errors session['reqparams'] = {} # @TODO request.params may contain multiple values per key... test & fix for k in request.params.iterkeys(): session['reqparams'][k] = request.params[k] session.save() redirect(url(controller='profile', action='edit')) return f(self) return new_f @checkMember def doEdit(self): m = self.lmf.getUser(session['identity']) if m.validate: # member locked for validation redirect(url(controller='error', action='forbidden')) else: changes = False if request.params['sn'] != m.sn or\ request.params['givenName'] != m.givenName or\ request.params['homePostalAddress'] != m.homePostalAddress or\ ('homePhone' in request.params and len(request.params['homePhone']) > 0 and request.params['homePhone'] != m.homePhone) or\ request.params['mobile'] != m.mobile or\ request.params['mail'] != m.mail or\ request.params['xmppID'] != m.xmppID: changes = True if changes: tm = TmpMember(m.uidNumber) tm.sn = str(request.params['sn'].encode('utf-8')) tm.gn = str(request.params['givenName'].encode('utf-8')) tm.homePostalAddress = str(request.params['homePostalAddress'].encode('utf-8')) if request.params.get('homePhone', '') == '' and not m.homePhone == '': tm.phone = '>>REMOVE<<' else: tm.phone = request.params['homePhone'] if request.params.get('xmppID', '') == '' and not m.xmppID == '': tm.xmppID = 'removed' else: tm.xmppID = request.params['xmppID'] tm.mobile = request.params['mobile'] tm.mail = request.params['mail'] Session.add(tm) Session.commit() session['flash'] = _('Changes saved!') session['flash_class'] = 'success' self.mailValidationRequired() else: session['flash'] = _('Nothing to save!') session['flash_class'] = 'info' if not request.params.get('userPassword', '') == '' and request.params['userPassword'] == request.params['userPassword2']: m.setPassword(request.params['userPassword']) self.lmf.saveMember(m, is_admin=False) session['secret'] = encodeAES(request.params['userPassword']) session['flash'] = _('Password updated!') session['flash_class'] = 'success' session.save() redirect(url(controller='profile', action='index')) def mailValidationRequired(self): body = 'Hi,\n' body += 'The following user has updated his profile which requires your approval:\n' body += session['identity'] + '\n' body += 'Please carefully review his changes and approve or reject them as required.\n\n' body += 'regards,\nMeMaTool' to = '*****@*****.**' subject = config.get('mematool.name_prefix') + ' mematool - request for validation' self.sendMail(to, subject, body) def setLang(self): if (not 'lang' in request.params): redirect(url(controller='members', action='showAllMembers')) if request.params['lang'] in ('en', 'lb', 'de'): session['language'] = request.params['lang'] session.save() set_lang(request.params['lang']) redirect(url(controller='members', action='showAllMembers')) def _resizeImage(self, img): try: o_img = Image.open(img) max_size = (240, 240) o_img.thumbnail(max_size, Image.ANTIALIAS) out = StringIO.StringIO() o_img.save(out, format='jpeg', quality=75) return base64.b64encode(out.getvalue()) except: import sys, traceback traceback.print_exc(file=sys.stdout) return None def editAvatar(self): c.heading = _('Edit avatar') try: member = self.lmf.getUser(session['identity']) member.avatarUrl = self.avatarUrl(member.uid, size=180) c.member = member return render('/profile/editAvatar.mako') except LookupError: print 'Edit :: No such user !' return 'ERROR 4x0' def doEditAvatar(self): if not 'avatar' in request.POST or not len(request.POST['avatar'].value) > 0: redirect(url(controller='profile', action='editAvatar')) try: img_param = request.POST['avatar'].file img = self._resizeImage(img_param) member = self.lmf.getUser(session['identity']) self.lmf.updateAvatar(member, img) except: import sys, traceback traceback.print_exc(file=sys.stdout) redirect(url(controller='profile', action='editAvatar')) def doDeleteAvatar(self): try: member = self.lmf.getUser(session['identity']) self.lmf.updateAvatar(member, None) except: import sys, traceback traceback.print_exc(file=sys.stdout) redirect(url(controller='profile', action='editAvatar')) def getAvatar(self): if (not 'member_id' in request.params): return '4x4 p0wer' try: member = self.lmf.getUser(request.params['member_id']) if not member.jpegPhoto is None: return member.avatar except: pass return '4x4 p0wer'