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)
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