Example #1
0
    def setUp(self):
        unittest.TestCase.setUp(self)

        self.username = '******'
        self.password = '******'

        ldap_connector = LdapConnector(username=self.username,
                                       password=self.password)
        self.ldapcon = ldap_connector.get_connection()
        self.ldmf = LdapModelFactory(self.ldapcon)
Example #2
0
    def setUp(self):
        unittest.TestCase.setUp(self)

        self.username = "******"
        self.password = "******"

        ldap_connector = LdapConnector(username=self.username, password=self.password)
        self.ldapcon = ldap_connector.get_connection()
        self.ldmf = LdapModelFactory(self.ldapcon)
Example #3
0
class StatisticsController(BaseController):

  def __init__(self):
    super(StatisticsController, self).__init__()
    self.lmf = LdapModelFactory()

  def __before__(self):
    super(StatisticsController, self).__before__()

    if not self.identity:
      redirect(url(controller='error', action='forbidden'))

  @BaseController.needAdmin
  def index(self):
    c.heading = _('Statistics')

    c.members = len(self.lmf.getUserList())
    activeMembers = self.lmf.getActiveMemberList()
    c.activeMembers = len(activeMembers)
    c.formerMembers = c.members - c.activeMembers

    c.paymentsOk = 0

    for uid in activeMembers:
      last_payment = None

      try:
        last_payment = Session.query(Payment).filter(and_(Payment.uid == uid, Payment.verified == 1)).order_by(Payment.date.desc()).limit(1)[0]
      except Exception as e:
        ''' Don't care if there is no payment '''
        print e
        print uid
        pass

      if last_payment:
        d = last_payment.date
        today = datetime.now().date()

        if d.year > today.year or (d.year == today.year and d.month >= today.month):
          c.paymentsOk += 1

    c.paymentsNotOk = c.activeMembers - c.paymentsOk

    return render('/statistics/index.mako')
Example #4
0
class TestLdapModelFactory(unittest.TestCase):
    def setUp(self):
        unittest.TestCase.setUp(self)

        self.username = '******'
        self.password = '******'

        ldap_connector = LdapConnector(username=self.username,
                                       password=self.password)
        self.ldapcon = ldap_connector.get_connection()
        self.ldmf = LdapModelFactory(self.ldapcon)

    def tearDown(self):
        unittest.TestCase.tearDown(self)
        self.ldapcon = None

    ################# User
    def test_getUser(self):
        user = self.ldmf.getUser(self.username)
        self.assertIsInstance(user, mematool.model.ldapmodel.Member)

    def test_getUserList(self):
        o = self.ldmf.getUserList()
        self.assertIsInstance(o, list)
        self.assertGreaterEqual(len(o), 1)

    def test_getActiveMemberList(self):
        o = self.ldmf.getActiveMemberList()
        self.assertIsInstance(o, list)
        self.assertGreaterEqual(len(o), 1)

    def test_getUserGroupList(self):
        o = self.ldmf.getUserGroupList(self.username)
        self.assertIsInstance(o, list)
        self.assertGreaterEqual(len(o), 1)

    def test_getHighestUidNumber(self):
        o = self.ldmf.getHighestUidNumber()
        self.assertIsInstance(o, str)
        self.assertRegexpMatches(o, r'^\d+$')
        o = int(o)
        self.assertGreaterEqual(o, 1000)

    def test_getUidNumberFromUid(self):
        o = self.ldmf.getUidNumberFromUid(self.username)
        self.assertIsInstance(o, str)
        self.assertRegexpMatches(o, r'^\d+$')
        o = int(o)
        self.assertGreaterEqual(o, 1000)

    '''
  def test_prepareVolatileAttribute(self):
    # @todo
    raise NotImplemented()

  def test__updateMember(self):
    # @todo
    raise NotImplemented()

  def test__addMember(self):
    # @todo
    raise NotImplemented()

  def test_deleteUser(self):
    # @todo
    raise NotImplemented()

  def test_changeUserGroup(self):
    # @todo
    raise NotImplemented()

  def test_updateAvatar(self):
    # @todo
    raise NotImplemented()
  '''

    ################# Group

    def test_getGroup(self):
        user = self.ldmf.getUser(self.username)
        self.assertIsInstance(user.groups, list)
        self.assertGreaterEqual(len(user.groups), 1)

        for g in user.groups:
            group = self.ldmf.getGroup(g)
            self.assertIsInstance(group, mematool.model.dbmodel.Group)

    def test_getGroupList(self):
        o = self.ldmf.getGroupList()
        self.assertIsInstance(o, list)
        self.assertGreaterEqual(len(o), 1)

    def test_getGroupMembers(self):
        user = self.ldmf.getUser(self.username)
        self.assertIsInstance(user.groups, list)
        self.assertGreaterEqual(len(user.groups), 1)

        for g in user.groups:
            o = self.ldmf.getGroupMembers(g)
            self.assertIsInstance(o, list)
            self.assertGreaterEqual(len(o), 1)

    def test_addDeleteGroup(self):
        # add
        self.assertTrue(self.ldmf.addGroup('test_group'))
        o = self.ldmf.getGroupList()
        self.assertIn('test_group', o)

        # delete
        self.assertTrue(self.ldmf.deleteGroup('test_group'))
        o = self.ldmf.getGroupList()
        self.assertNotIn('test_group', o)

    def test_getHighestGidNumber(self):
        o = self.ldmf.getHighestGidNumber()
        self.assertIsInstance(o, str)
        self.assertRegexpMatches(o, r'^\d+$')
        o = int(o)
        self.assertGreaterEqual(o, 1000)

    ################# Domain

    def test_addDeleteDomain(self):
        res = self.ldmf.addDomain('example.com')
        self.assertTrue(res)

        res = self.ldmf.getDomainList()
        self.assertIn('example.com', res)

        res = self.ldmf.deleteDomain('example.com')
        self.assertTrue(res)

        res = self.ldmf.getDomainList()
        self.assertNotIn('example.com', res)

    def test_getDomain(self):
        res = self.ldmf.addDomain('example.com')
        self.assertTrue(res)

        d = self.ldmf.getDomain('example.com')
        self.assertIsInstance(d, mematool.model.ldapmodel.Domain)

        res = self.ldmf.deleteDomain('example.com')
        self.assertTrue(res)

    def test_getDomainList(self):
        res = self.ldmf.getDomainList()
        self.assertIsInstance(res, list)

    ################# Alias

    def test_getAlias(self):
        res = self.ldmf.addDomain('example.com')

        alias = mematool.model.ldapmodel.Alias()
        alias.dn_mail = '*****@*****.**'
        alias.mail = ['*****@*****.**']
        alias.maildrop = ['*****@*****.**']

        try:
            res = self.ldmf.addAlias(alias)
            self.assertTrue(res)
        except mematool.helpers.exceptions.EntryExists:
            pass

        res = self.ldmf.getAlias('*****@*****.**')
        self.assertIsInstance(res, mematool.model.ldapmodel.Alias)

        res = self.ldmf.deleteAlias('*****@*****.**')
        self.assertTrue(res)

        res = self.ldmf.deleteDomain('example.com')
        self.assertTrue(res)

    def test_getAliasList(self):
        res = self.ldmf.getAliasList('example.com')
        self.assertIsInstance(res, list)

    def test_getMaildropList(self):
        res = self.ldmf.getMaildropList('*****@*****.**')
        self.assertIsInstance(res, dict)

    def test_addDeleteAlias(self):
        res = self.ldmf.addDomain('example.com')
        #self.assertTrue(res)

        alias = mematool.model.ldapmodel.Alias()
        alias.dn_mail = '*****@*****.**'
        alias.mail = ['*****@*****.**']
        alias.maildrop = ['*****@*****.**']

        try:
            res = self.ldmf.addAlias(alias)
            self.assertTrue(res)
        except mematool.helpers.exceptions.EntryExists:
            pass

        res = self.ldmf.deleteAlias('*****@*****.**')
        self.assertTrue(res)

        res = self.ldmf.deleteDomain('example.com')
        self.assertTrue(res)

    '''
Example #5
0
 def __init__(self):
   super(PreferencesController, self).__init__()
   self.lmf = LdapModelFactory()
Example #6
0
class PreferencesController(BaseController):
  def __init__(self):
    super(PreferencesController, self).__init__()
    self.lmf = LdapModelFactory()

  def __before__(self):
    super(PreferencesController, self).__before__()

  def _sidebar(self):
    super(PreferencesController, self)._sidebar()

    c.actions.append({'name' : _('Profile'), 'args' : {'controller' : 'profile', '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 preferences')
    c.formDisabled = ''

    try:
      member = self.lmf.getUser(session['identity'])
      c.member = member
      pref = Session.query(Preferences).filter(Preferences.uidNumber == member.uidNumber).all()

      c.language = 'en'

      if len(pref) > 0:
        for p in pref:
          if p.key == 'language':
            c.language = p.value

      c.languages = self.languages

      return render('preferences/edit.mako')

    except LookupError:
      print 'Edit :: No such user !'

    return 'ERROR 4x0'

  def checkPreferences(f):
    def new_f(self):
      # @TODO request.params may contain multiple values per key... test & fix
      formok = True
      errors = []

      try:
        ParamChecker.checkString('language', min_len=2, max_len=2)
      except InvalidParameterFormat:
        checkOK = False
        errors.append(_('Invalid language'))

      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='preferences', action='edit'))

      return f(self)
    return new_f

  @checkPreferences
  def doEdit(self):
    member = self.lmf.getUser(session['identity'])

    try:
      language = Session.query(Preferences).filter(and_(Preferences.uidNumber == member.uidNumber, Preferences.key == 'language')).one()
      language.last_change = datetime.now()
      language.value = request.params['language']

      session['language'] = language.value
      session['flash'] = _('Changes saved!')
      session['flash_class'] = 'success'
    except NoResultFound:
      pref = Preferences()
      pref.uidNumber = member.uidNumber
      pref.last_change = datetime.now().date()
      pref.key = 'language'
      pref.value = request.params['language']
      Session.add(pref)

      session['language'] = request.params['language']

      session['flash'] = _('Changes saved!')
      session['flash_class'] = 'success'
    except:
      session['flash'] = _('Unknown error, nothing saved')
      session['flash_class'] = 'error'

    Session.commit()

    session.save()
    redirect(url(controller='preferences', action='edit'))
Example #7
0
class TestLdapModelFactory(unittest.TestCase):
    def setUp(self):
        unittest.TestCase.setUp(self)

        self.username = "******"
        self.password = "******"

        ldap_connector = LdapConnector(username=self.username, password=self.password)
        self.ldapcon = ldap_connector.get_connection()
        self.ldmf = LdapModelFactory(self.ldapcon)

    def tearDown(self):
        unittest.TestCase.tearDown(self)
        self.ldapcon = None

    ################# User
    def test_getUser(self):
        user = self.ldmf.getUser(self.username)
        self.assertIsInstance(user, mematool.model.ldapmodel.Member)

    def test_getUserList(self):
        o = self.ldmf.getUserList()
        self.assertIsInstance(o, list)
        self.assertGreaterEqual(len(o), 1)

    def test_getActiveMemberList(self):
        o = self.ldmf.getActiveMemberList()
        self.assertIsInstance(o, list)
        self.assertGreaterEqual(len(o), 1)

    def test_getUserGroupList(self):
        o = self.ldmf.getUserGroupList(self.username)
        self.assertIsInstance(o, list)
        self.assertGreaterEqual(len(o), 1)

    def test_getHighestUidNumber(self):
        o = self.ldmf.getHighestUidNumber()
        self.assertIsInstance(o, str)
        self.assertRegexpMatches(o, r"^\d+$")
        o = int(o)
        self.assertGreaterEqual(o, 1000)

    def test_getUidNumberFromUid(self):
        o = self.ldmf.getUidNumberFromUid(self.username)
        self.assertIsInstance(o, str)
        self.assertRegexpMatches(o, r"^\d+$")
        o = int(o)
        self.assertGreaterEqual(o, 1000)

    """
  def test_prepareVolatileAttribute(self):
    # @todo
    raise NotImplemented()

  def test__updateMember(self):
    # @todo
    raise NotImplemented()

  def test__addMember(self):
    # @todo
    raise NotImplemented()

  def test_deleteUser(self):
    # @todo
    raise NotImplemented()

  def test_changeUserGroup(self):
    # @todo
    raise NotImplemented()

  def test_updateAvatar(self):
    # @todo
    raise NotImplemented()
  """

    ################# Group

    def test_getGroup(self):
        user = self.ldmf.getUser(self.username)
        self.assertIsInstance(user.groups, list)
        self.assertGreaterEqual(len(user.groups), 1)

        for g in user.groups:
            group = self.ldmf.getGroup(g)
            self.assertIsInstance(group, mematool.model.dbmodel.Group)

    def test_getGroupList(self):
        o = self.ldmf.getGroupList()
        self.assertIsInstance(o, list)
        self.assertGreaterEqual(len(o), 1)

    def test_getGroupMembers(self):
        user = self.ldmf.getUser(self.username)
        self.assertIsInstance(user.groups, list)
        self.assertGreaterEqual(len(user.groups), 1)

        for g in user.groups:
            o = self.ldmf.getGroupMembers(g)
            self.assertIsInstance(o, list)
            self.assertGreaterEqual(len(o), 1)

    def test_addDeleteGroup(self):
        # add
        self.assertTrue(self.ldmf.addGroup("test_group"))
        o = self.ldmf.getGroupList()
        self.assertIn("test_group", o)

        # delete
        self.assertTrue(self.ldmf.deleteGroup("test_group"))
        o = self.ldmf.getGroupList()
        self.assertNotIn("test_group", o)

    def test_getHighestGidNumber(self):
        o = self.ldmf.getHighestGidNumber()
        self.assertIsInstance(o, str)
        self.assertRegexpMatches(o, r"^\d+$")
        o = int(o)
        self.assertGreaterEqual(o, 1000)

    ################# Domain

    def test_addDeleteDomain(self):
        res = self.ldmf.addDomain("example.com")
        self.assertTrue(res)

        res = self.ldmf.getDomainList()
        self.assertIn("example.com", res)

        res = self.ldmf.deleteDomain("example.com")
        self.assertTrue(res)

        res = self.ldmf.getDomainList()
        self.assertNotIn("example.com", res)

    def test_getDomain(self):
        res = self.ldmf.addDomain("example.com")
        self.assertTrue(res)

        d = self.ldmf.getDomain("example.com")
        self.assertIsInstance(d, mematool.model.ldapmodel.Domain)

        res = self.ldmf.deleteDomain("example.com")
        self.assertTrue(res)

    def test_getDomainList(self):
        res = self.ldmf.getDomainList()
        self.assertIsInstance(res, list)

    ################# Alias

    def test_getAlias(self):
        res = self.ldmf.addDomain("example.com")

        alias = mematool.model.ldapmodel.Alias()
        alias.dn_mail = "*****@*****.**"
        alias.mail = ["*****@*****.**"]
        alias.maildrop = ["*****@*****.**"]

        try:
            res = self.ldmf.addAlias(alias)
            self.assertTrue(res)
        except mematool.helpers.exceptions.EntryExists:
            pass

        res = self.ldmf.getAlias("*****@*****.**")
        self.assertIsInstance(res, mematool.model.ldapmodel.Alias)

        res = self.ldmf.deleteAlias("*****@*****.**")
        self.assertTrue(res)

        res = self.ldmf.deleteDomain("example.com")
        self.assertTrue(res)

    def test_getAliasList(self):
        res = self.ldmf.getAliasList("example.com")
        self.assertIsInstance(res, list)

    def test_getMaildropList(self):
        res = self.ldmf.getMaildropList("*****@*****.**")
        self.assertIsInstance(res, dict)

    def test_addDeleteAlias(self):
        res = self.ldmf.addDomain("example.com")
        # self.assertTrue(res)

        alias = mematool.model.ldapmodel.Alias()
        alias.dn_mail = "*****@*****.**"
        alias.mail = ["*****@*****.**"]
        alias.maildrop = ["*****@*****.**"]

        try:
            res = self.ldmf.addAlias(alias)
            self.assertTrue(res)
        except mematool.helpers.exceptions.EntryExists:
            pass

        res = self.ldmf.deleteAlias("*****@*****.**")
        self.assertTrue(res)

        res = self.ldmf.deleteDomain("example.com")
        self.assertTrue(res)

    """
Example #8
0
 def __init__(self):
   super(MembersController, self).__init__()
   self.lmf = LdapModelFactory()
Example #9
0
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'))
Example #10
0
 def __init__(self):
   super(StatisticsController, self).__init__()
   self.lmf = LdapModelFactory()
Example #11
0
 def __init__(self):
   super(PaymentsController, self).__init__()
   self.lmf = LdapModelFactory()
Example #12
0
class PaymentsController(BaseController):
  def __init__(self):
    super(PaymentsController, self).__init__()
    self.lmf = LdapModelFactory()

  def __before__(self, action, **param):
    super(PaymentsController, self).__before__()

  def _sidebar(self):
    super(PaymentsController, self)._sidebar()

    c.actions.append({'name' : _('All payments'), 'args' : {'controller' : 'payments', 'action' : 'listPayments'}})
    c.actions.append({'name' : _('Outstanding payment'), 'args' : {'controller' : 'payments', 'action' : 'index'}})

  def index(self):
    if self.isAdmin() or self.lmf.isUserInGroup(self.identity, 'office'):
      return self.showOutstanding()

    return redirect(url(controller='payments', action='listPayments', member_id=self.identity))

  @BaseController.needFinanceAdmin
  def validatePayment(self):
    """ Validate a payment specified by an id """
    try:
      ParamChecker.checkUsername('member_id', param=True)
      ParamChecker.checkInt('idPayment', param=True)
    except:
      redirect(url(controller='payments', action='index'))

    try:
      np = Session.query(Payment).filter(Payment.id == request.params['idPayment']).one()

      if np.verified:
        np.verified = False
      else:
        np.verified = True
      Session.commit()

      session['flash'] = _('Payment validation successfully toggled')
      session['flash_class'] = 'success'
    except:
      session['flash'] = _('Saving payment failed')
      session['flash_class'] = 'error'

    session.save()

    redirect(url(controller='payments', action='listPayments', member_id=request.params['member_id']))

  def _getLastPayment(self, uid):
    member = self.lmf.getUser(uid)
    lastDate = parser.parse(member.arrivalDate)

    try:
      p = Session.query(Payment).filter(and_(Payment.uid == uid, or_(Payment.status == 0, Payment.status == 2))).order_by(Payment.date.desc()).first()
      lastDate = p.date + relativedelta(months = + 1)
    except Exception as e:
      pass

    return lastDate

  def bulkAdd(self):
    try:
      ParamChecker.checkUsername('member_id', param=True)
    except:
      redirect(url(controller='payments', action='index'))

    c.member_id = request.params['member_id']
    c.heading = _('Add bulk payments')

    return render('/payments/bulkAdd.mako')

  def doBulkAdd(self):
    try:
      ParamChecker.checkUsername('member_id', param=True)
      ParamChecker.checkInt('months', param=True, max_len=2)
    except:
      redirect(url(controller='payments', action='index'))

    lastDate = self._getLastPayment(request.params['member_id'])
    months = int(request.params['months'])
    verified = False

    if self.isFinanceAdmin():
      try:
        ParamChecker.checkInt('verified', param=True, max_len=1)
        verified = True
      except:
        pass

    try:
      for i in range(months):
        p = Payment()
        p.uid = request.params['member_id']
        p.date = lastDate + relativedelta(months = i)
        p.status = 0
        p.verified = verified

        Session.add(p)

      Session.commit()

      session['flash'] = _('Payments added')
      session['flash_class'] = 'success'
    except Exception as e:
      session['flash'] = _('Operation failed')
      session['flash_class'] = 'error'

    session.save()

    redirect(url(controller='payments', action='listPayments', member_id=request.params['member_id']))

  @BaseController.needAdmin
  def showOutstanding(self):
    """ Show which users still need to pay their membership fees and if a reminder has already been sent """

    showAll = False
    if request.params.get('showAll', '') == '1':
      showAll = True

    activeMembers = self.lmf.getActiveMemberList()

    # Prepare add payment form
    c.heading = _('Outstanding payments')
    c.members = []
    c.member_ids = []
    for uid in activeMembers:
      last_payment = None

      try:
        last_payment = Session.query(Payment).filter(and_(Payment.uid == uid, Payment.verified == 1)).order_by(Payment.date.desc()).limit(1)[0]
      except:
        ''' Don't care if there is no payment '''
        pass

      m = self.lmf.getUser(uid)
      m.paymentGood = False

      if last_payment:
        d = last_payment.date
        today = datetime.now().date()

        if d.year > today.year or (d.year == today.year and d.month >= today.month):
          m.paymentGood = True

      if not m.paymentGood or showAll:
        c.members.append(m)

      c.member_ids.append(uid)

    return render('/payments/showOutstanding.mako')

  def listPayments(self):
    """ Show a specific user's payments """
    if not 'member_id' in request.params:
      if not self.isAdmin() and not self.isFinanceAdmin():
        redirect(url(controller='error', action='forbidden'))
      else:
        redirect(url(controller='payments', action='showOutstanding', showAll='1'))
    elif not self.isAdmin() and not self.isFinanceAdmin() and not request.params['member_id'] == self.identity:
      redirect(url(controller='error', action='forbidden'))

    year = None

    if year is None:
      try:
        ParamChecker.checkInt('year', param=True, max_len=4)
        if int(request.params['year']) > 1970 and int(request.params['year']) < 2222:
          year = int(request.params['year'])
      except:
        pass

    if year is None:
      try:
        ParamChecker.checkUsername('member_id', param=True)
        year = self._getLastPayment(request.params['member_id']).year
      except:
        pass

    if year is None:
      year = datetime.now().year

    c.heading = _('Payments for the year %s, user %s') % (str(year), request.params['member_id'])
    c.member_id = request.params['member_id']

    ## consider pagination
    # http://pylonsbook.com/en/1.1/starting-the-simplesite-tutorial.html#using-pagination
    try:
      #c.member.leavingDate = date(int(member.leavingDate[:4]),int(member.leavingDate[5:6]),int(member.leavingDate[7:8]))
      ## ideally, fetch monthly from member and the rest from payment (one to many relation)
      ## http://www.sqlalchemy.org/docs/05/reference/ext/declarative.html

      y_start = date(year, 1, 1)
      y_end = date(year, 12, 31)
      payment_sql = Session.query(Payment).filter(Payment.uid == request.params['member_id']).filter(Payment.date.between(y_start, y_end)).order_by(Payment.date.desc()).all()

      payments = {}
      c.unverifiedPledges = 0
      for p in payment_sql:
        if p.verified == 0:
          c.unverifiedPledges += 1
        payments[p.date.month] = p

      c.year = year
      c.payments = payments

    except AttributeError, e:
      return 'This member has made no payments o.O ?!: %s' % e
    except NoResultFound:
      return "this member has no payments on records"  # replace by "this member has made no payments" message
Example #13
0
 def __init__(self):
   super(ProfileController, self).__init__()
   self.lmf = LdapModelFactory()
Example #14
0
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'
Example #15
0
 def get_ldapMF(self):
     return LdapModelFactory(self.get_ldapcon())
Example #16
0
class GroupsController(BaseController):
  def __init__(self):
    super(GroupsController, self).__init__()
    self.lmf = LdapModelFactory()

  def __before__(self, action, **param):
    super(GroupsController, self).__before__()

  def _sidebar(self):
    super(GroupsController, self)._sidebar()

    c.actions.append({'name' : _('Show all groups'), 'args' : {'controller' : 'groups', 'action' : 'listGroups'}})
    c.actions.append({'name' : _('Add Group'), 'args' : {'controller' : 'groups', 'action' : 'editGroup'}})
    c.actions.append({'name' : _('Members'), 'args' : {'controller' : 'members', 'action' : 'index'}})

  def index(self):
    if self.lmf.isUserInGroup(self.identity, 'office') or self.lmf.isUserInGroup(self.identity, 'sysops'):
      return self.listGroups()

    return redirect(url(controller='profile', action='index'))

  @BaseController.needGroup('superadmins')
  def listGroups(self):
    c.heading = _('Managed groups')

    c.groups = self.lmf.getManagedGroupList()

    return render('/groups/listGroups.mako')

  @BaseController.needGroup('superadmins')
  def editGroup(self):
    # vary form depending on mode (do that over ajax)
    if request.params.get('gid', '') == '':
      c.group = Group()
      action = 'Adding'
      c.gid = ''
    else:
      try:
        ParamChecker.checkUsername('gid', param=True)
      except:
        redirect(url(controller='groups', action='index'))

      action = 'Editing'
      c.gid = request.params['gid']
      try:
        c.group = self.lmf.getGroup(request.params['gid'])
        users = ''

        for u in c.group.users:
          if not users == '':
            users += '\n'
          users += u

        c.group.users = users
      except LookupError:
        # @TODO implement better handler
        print 'No such group!'
        redirect(url(controller='groups', action='index'))

    c.heading = '{0} group'.format(action)

    return render('/groups/editGroup.mako')

  def checkEdit(f):
    def new_f(self):
      if not 'gid' in request.params:
        redirect(url(controller='groups', action='index'))
      else:
        formok = True
        errors = []
        items = {}

        try:
          ParamChecker.checkUsername('gid', param=True)
        except:
          formok = False
          errors.append(_('Invalid group ID'))

        items['users'] = []

        if 'users' in request.params:
          try:
            #ParamChecker.checkString('users', param=True, min_len=-1, max_len=9999, regex=r'([\w]{1,20}\n?)*')

            for k in request.params['users'].split('\n'):
              m = k.replace('\r', '').replace(' ', '')
              if m == '':
                continue
              else:
                ParamChecker.checkUsername(m, param=False)
                items['users'].append(m)
          except InvalidParameterFormat as ipf:
            formok = False
            errors.append(_('Invalid user name(s)'))

        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='groups', action='editGroup', gid=request.params['gid']))
        else:
          items['gid'] = request.params['gid']

      return f(self, items)
    return new_f

  @BaseController.needGroup('superadmins')
  @checkEdit
  @restrict('POST')
  def doEditGroup(self, items):
    if not self.lmf.addGroup(items['gid']):
      session['flash'] = _('Failed to add group!')
      session['flash_class'] = 'error'
      session.save()
    else:
      try:
        lgrp_members = self.lmf.getGroupMembers(items['gid'])
      except LookupError:
        lgrp_members = []

      # Adding new members
      for m in items['users']:
        if not m in lgrp_members:
          #print 'adding -> ' + str(m)
          self.lmf.changeUserGroup(m, items['gid'], True)

      # Removing members
      for m in lgrp_members:
        if not m in items['users']:
          #print 'removing -> ' + str(m)
          self.lmf.changeUserGroup(m, items['gid'], False)

      # @TODO add group if not exist

      session['flash'] = _('Group saved successfully')
      session['flash_class'] = 'success'
      session.save()

    redirect(url(controller='groups', action='index'))

  @BaseController.needGroup('superadmins')
  def unmanageGroup(self):
    try:
      ParamChecker.checkUsername('gid', param=True)
    except:
      redirect(url(controller='groups', action='index'))

    result = self.lmf.unmanageGroup(request.params['gid'])

    if result:
      session['flash'] = _('Group no longer managed')
      session['flash_class'] = 'success'
    else:
      session['flash'] = _('Failed to remove group from management!')
      session['flash_class'] = 'error'

    session.save()

    redirect(url(controller='groups', action='index'))

  @BaseController.needGroup('superadmins')
  def deleteGroup(self):
    try:
      ParamChecker.checkUsername('gid', param=True)
    except:
      redirect(url(controller='groups', action='index'))

    result = self.lmf.deleteGroup(request.params['gid'])

    if result:
      session['flash'] = _('Group successfully deleted')
      session['flash_class'] = 'success'
    else:
      session['flash'] = _('Failed to delete group!')
      session['flash_class'] = 'error'

    session.save()

    redirect(url(controller='groups', action='index'))