def test_reset(self):
     """
     Make sure that resetting the password works.
     Trying to reset an email that does not exist should return an error.
     Make sure that resetting the password does not immediately change the password.
     Make sure that resetting the password sends a confirmation email.
     Make sure that reset confirmation works.
     """
     # Reset an unfamiliar email
     self.assertEqual(simplejson.dumps({'isOk': 0}), self.app.post(url('person_reset'), dict(email=email)).body)
     # Add person
     meta.Session.add(model.Person(username, model.hashString(password), nickname, email))
     meta.Session.commit()
     # Reset password
     self.assertEqual(simplejson.dumps({'isOk': 1}), self.app.post(url('person_reset'), dict(email=email)).body)
     # Make sure the confirmation exists
     self.assertEqual(meta.Session.query(model.PersonConfirmation).filter_by(username=username).count(), 1)
     # Activate confirmation
     self.app.get(url('person_confirm', ticket=meta.Session.query(model.PersonConfirmation.ticket).filter_by(username=username).first()[0]))
     # Make sure the password has changed
     self.assertEqual(meta.Session.query(model.Person).filter_by(password_hash=model.hashString(password)).count(), 0)
示例#2
0
def run():
    """
    Add an account
    """
    # Initialize
    personPacks = []
    newPersonCount = 0
    peoplePath = '.people.cfg'
    # If a configuration file exists,
    if os.path.exists(peoplePath):
        configuration = ConfigParser.ConfigParser()
        configuration.read(peoplePath)
        for sectionName in configuration.sections():
            personPacks.append((
                configuration.get(sectionName, 'username'),
                configuration.get(sectionName, 'password'),
                sectionName,
                configuration.get(sectionName, 'email'),
                configuration.get(sectionName, 'email_sms'),
                configuration.get(sectionName, 'is_super', '').capitalize() == 'True',
            ))
    # Otherwise, 
    else:
        print 'Missing person configuration path: ' + peoplePath
        # Prompt for information
        personPacks.append((
            raw_input('Username: '******'Nickname: '),
            raw_input('Email: '),
            raw_input('Email SMS: '),
            raw_input('Super (y/[n])? ').lower() == 'y'))
    # For each person,
    for personPack in personPacks:
        # Extract
        username, password, nickname, email, email_sms, is_super = personPack
        # If the person exists,
        if meta.Session.query(model.Person).filter_by(username=username).first():
            continue
        # Add the person
        person = model.Person(
            username=username, 
            password_hash=model.hashString(password), 
            nickname=unicode(nickname), 
            email=email, 
            email_sms=email_sms,
            is_super=is_super,
        )
        meta.Session.add(person)
        newPersonCount += 1
    # Return
    return '%s people added' % newPersonCount
 def test_index(self):
     """
     Assert that the index page shows how many accounts are on file.
     """
     # Initialize
     url_test = url('person_index')
     # Make sure that we begin with 0 people
     self.assert_('population of 0' in self.app.get(url_test))
     # Add person
     meta.Session.add(model.Person(username, model.hashString(password), nickname, email))
     meta.Session.commit()
     # Make sure that we now have 1 person
     self.assert_('population of 1' in self.app.get(url_test))
 def login_(self):
     """
     Process login credentials.
     """
     # Check username
     username = str(request.POST.get('username', ''))
     person = meta.Session.query(model.Person).filter_by(username=username).first()
     # If the username does not exist,
     if not person:
         return dict(isOk=0)
     # Check password
     password_hash = model.hashString(str(request.POST.get('password', '')))
     # If the password is incorrect,
     if password_hash != StringIO.StringIO(person.password_hash).read():
         person.rejection_count += 1
         meta.Session.commit()
         return dict(isOk=0)
     # If there have been too many rejections,
     if person.rejection_count >= parameter.REJECTION_LIMIT:
         # Expect a recaptcha
         challenge = request.POST.get('recaptcha_challenge_field', '')
         response = request.POST.get('recaptcha_response_field', '')
         privateKey = config['extra']['recaptcha']['private']
         remoteIP = request.environ['REMOTE_ADDR']
         # Validate recaptcha
         result = captcha.submit(challenge, response, privateKey, remoteIP)
         # If the recaptcha is invalid,
         if not result.is_valid:
             return dict(isOk=0)
     # Compute offset_in_minutes
     clientTimezoneOffset = int(request.POST.getone('offset_in_minutes'))
     clientNow = datetime.datetime.utcnow() - datetime.timedelta(minutes=clientTimezoneOffset)
     serverNow = datetime.datetime.now()
     offset_in_minutes = (clientNow - serverNow).seconds / 60
     # Round to the nearest five minutes modulo the number of minutes in a day
     offset_in_minutes = (int(round(offset_in_minutes / 5.)) * 5) % 1440
     # Save session
     session['offset_in_minutes'] = offset_in_minutes
     session['personID'] = person.id
     session['nickname'] = person.nickname
     session['is_super'] = person.is_super
     session.save()
     # Save person
     person.offset_in_minutes = offset_in_minutes
     person.rejection_count = 0
     meta.Session.commit()
     # Return
     return dict(isOk=1)
 def test_login(self):
     """
     Make sure that logging in works.
     Ensure that the login page shows.
     Ensure that bad credentials result in an error message.
     Ensure that good credentials result in a proper redirect.
     """
     # Initialize
     url_test = url('person_update')
     # Assert that the login page shows and stores url
     self.assert_('Login' in self.app.get(url('person_login', url=h.encodeURL(url_test))))
     # Add person
     meta.Session.add(model.Person(username, model.hashString(password), nickname, email))
     meta.Session.commit()
     # Log in using bad credentials
     self.assertEqual(simplejson.dumps({'isOk': 0}), self.app.post(url('person_login_'), dict(username=username, password=password + 'x', offset_in_minutes=0)).body)
     # Log in using good credentials
     self.assertEqual(simplejson.dumps({'isOk': 1}), self.app.post(url('person_login_'), dict(username=username, password=password, offset_in_minutes=0)).body)
 def test_logout(self):
     """
     Make sure that logging out works.
     If the person is logged in, make sure the person gets logged out
     and is redirected properly.  If the person is already logged out, 
     return the user to the page before the user tried to log out.
     """
     # Initialize
     url_test = url('person_index')
     # Add person
     meta.Session.add(model.Person(username, model.hashString(password), nickname, email))
     meta.Session.commit()
     # Logging out should redirect back
     self.assert_(url_test in self.app.get(url('person_logout', url=h.encodeURL(url_test))))
     # Log in
     self.assert_('Login' in self.app.get(url('person_login', url=h.encodeURL(url_test))))
     self.assertEqual(simplejson.dumps({'isOk': 1}), self.app.post(url('person_login_'), dict(username=username, password=password, offset_in_minutes=0)).body)
     # Logging out should redirect back
     self.assert_(url_test in self.app.get(url('person_logout', url=h.encodeURL(url_test))))
 def test_update(self):
     """
     Make sure that updating credentials works.
     Make sure the update page only appears when the user is logged in.
     Make sure the update form is filled with the user's credentials.
     Make sure that update_ only works when the user is logged in.
     Make sure that update_ works and sends a confirmation email.
     Make sure that update confirmation works.
     """
     # Assert that we get a blank page if the person is not logged in
     self.assertEqual('', self.app.post(url('person_update')).body)
     self.assertEqual(simplejson.dumps({'isOk': 0}), self.app.post(url('person_update_')).body)
     # Add person
     meta.Session.add(model.Person(username, model.hashString(password), nickname, email, email_sms))
     meta.Session.commit()
     # Log in
     self.app.post(url('person_login_'), dict(username=username, password=password, offset_in_minutes=0))
     # Assert that the update form is filled with the user's credentials
     responseBody = self.app.get(url('person_update')).body
     self.assert_(username in responseBody)
     self.assert_(nickname in responseBody)
     self.assert_(email in responseBody)
     self.assert_(email_sms in responseBody)
     # Update credentials
     newUsername = store.makeRandomString(16)
     newPassword = store.makeRandomString(16)
     newNickname = unicode(store.makeRandomString(16))
     newEmail = re.sub(r'.*@', store.makeRandomString(16) + '@', email)
     newEmailSMS = re.sub(r'.*@', store.makeRandomString(16) + '@', email)
     self.assertEqual(simplejson.dumps({'isOk': 1}), self.app.post(url('person_update_'), dict(username=newUsername, password=newPassword, nickname=newNickname, email=newEmail, email_sms=newEmailSMS)).body)
     # Make sure the credentials have not changed yet
     self.assertEqual(meta.Session.query(model.Person).filter_by(username=newUsername, password_hash=model.hashString(newPassword), nickname=newNickname, email=newEmail, email_sms=newEmailSMS).count(), 0)
     # Activate confirmation
     self.app.get(url('person_confirm', ticket=meta.Session.query(model.PersonConfirmation.ticket).filter_by(username=newUsername).first()[0]))
     # Make sure the credentials have changed
     self.assertEqual(meta.Session.query(model.Person).filter_by(username=newUsername, password_hash=model.hashString(newPassword), nickname=newNickname, email=newEmail, email_sms=newEmailSMS).count(), 1)
def changeAccount(valueByName, action, templatePath, person=None):
    """
    Validate values and send confirmation email if values are okay.
    """
    try:
        # Validate form
        form = PersonForm().to_python(valueByName, person)
    except formencode.Invalid, error:
        return {'isOk': 0, 'errorByID': error.unpack_errors()}
    else:
        # Purge expired confirmations
        purgeExpiredPersonConfirmations()
        # Prepare confirmation
        confirmation = model.PersonConfirmation(form['username'],
            model.hashString(form['password']), form['nickname'],
            form['email'], form['email_sms'])
        confirmation.person_id = person.id if person else None
        confirmation.ticket = store.makeRandomUniqueTicket(parameter.TICKET_LENGTH, meta.Session.query(model.PersonConfirmation))
        confirmation.when_expired = datetime.datetime.now() + datetime.timedelta(days=parameter.TICKET_LIFESPAN_IN_DAYS)
        meta.Session.add(confirmation) 
        meta.Session.commit()
        # Prepare recipient
        toByValue = dict(nickname=form['nickname'], email=form['email'])
        # Prepare subject
        subject = '[%s] Confirm %s' % (parameter.SITE_NAME, action)
        # Prepare body
        c.ticket = confirmation.ticket
        c.when_expired = confirmation.when_expired
        c.username = form['username']
        c.action = action