Update tests for auth module, and fix some bugs discovered in auth module.

This commit is contained in:
James Valleroy 2013-11-04 00:30:21 +00:00 committed by Nick Daly
parent 2abe8559e5
commit f7ad1089a5
2 changed files with 50 additions and 38 deletions

View File

@ -9,22 +9,30 @@
import cherrypy
import urllib
from passlib.hash import bcrypt
from passlib.exc import PasswordSizeError
import cfg
import random
import time
from model import User
cfg.session_key = '_cp_username'
def add_user(username, passphrase, name='', email='', expert=False):
"""Add a new user with specified username and passphrase.
"""
error = None
if not username: error = "Must specify a username!"
if not password: error = "Must specify a password!"
if not passphrase: error = "Must specify a passphrase!"
if error is None:
# hash the password whether the user exists, to foil timing
# side-channel attacks
pass_hash = bcrypt.encrypt(password)
try:
pass_hash = bcrypt.encrypt(passphrase)
except PasswordSizeError:
error = "Password is too long."
if error is None:
if username in cfg.users.get_all():
error = "User already exists!"
else:
@ -38,7 +46,7 @@ def add_user(username, passphrase, name='', email='', expert=False):
'salt':pass_hash[7:29], # for bcrypt
}
new_user = User(di)
cfg.users.set(username,newuser)
cfg.users.set(username,new_user)
if error:
cfg.log(error)
@ -55,13 +63,19 @@ def check_credentials(username, passphrase):
cfg.log(error)
return error
if username in cfg.users:
u = cfg.users[username]
else:
u = None
# hash the password whether the user exists, to foil timing
# side-channel attacks
pass_hash = bcrypt.encrypt(passphrase, salt=u['salt'])
try:
if username in cfg.users:
u = cfg.users[username]
pass_hash = bcrypt.encrypt(passphrase, salt=u['salt'])
else:
u = None
pass_hash = bcrypt.encrypt(passphrase)
except PasswordSizeError:
error = "Password is too long."
cfg.log(error)
return error
if u is None or u['passphrase'] != pass_hash:
error = "Bad user-name or password."

View File

@ -26,45 +26,43 @@ class Auth(unittest.TestCase):
cfg.users.remove(user[0])
cfg.users.close()
def test_password_check(self):
self.add_user("test_user", "password")
def test_add_user(self):
self.assertIsNone(auth.add_user("test_user", "password"))
self.assertIsNotNone(auth.add_user(None, "password"))
self.assertIsNotNone(auth.add_user("test_user", None))
self.assertIsNotNone(auth.add_user("test_user", "password"))
# check_credentials returns None if there is no error, or returns error string
def test_password_check(self):
auth.add_user("test_user", "password")
# check_credentials returns None if there is no error,
# or returns error string
self.assertIsNone(auth.check_credentials("test_user", "password"))
self.assertIsNotNone(auth.check_credentials("test_user", "wrong"))
def test_salt_check(self):
test_user = self.add_user("test_user", "password", "abcdefghijklmnopqrstuv")
def test_nonexistent_user(self):
self.assertIsNotNone(auth.check_credentials("test_user", "password"))
def test_password_too_long(self):
password = "x" * 4097
self.assertIsNotNone(auth.add_user("test_user", password))
self.assertIsNotNone(auth.check_credentials("test_user", password))
def test_salt_is_random(self):
test_user1 = self.add_user("test_user1", "password")
test_user2 = self.add_user("test_user2", "password")
self.assertNotEqual(test_user1["salt"], test_user2["salt"])
auth.add_user("test_user1", "password")
auth.add_user("test_user2", "password")
self.assertNotEqual(
cfg.users["test_user1"]["salt"],
cfg.users["test_user2"]["salt"]
)
def test_hash_is_random(self):
test_user1 = self.add_user("test_user1", "password")
test_user2 = self.add_user("test_user2", "password")
self.assertNotEqual(test_user1["passphrase"], test_user2["passphrase"])
# set fake_salt if you want to store an invalid salt
def add_user(self, test_username, passphrase='', fake_salt=None):
test_user = self.create_user(test_username, passphrase, fake_salt)
cfg.users.set(test_username,test_user)
return test_user
def create_user(self, username, passphrase='', fake_salt=None):
test_user = User()
test_user["username"] = username
pass_hash = bcrypt.encrypt(passphrase)
test_user["passphrase"] = pass_hash
if fake_salt:
test_user["salt"] = fake_salt
else:
# for bcrypt, the salt is output as part of the hash
test_user["salt"] = pass_hash[7:29]
return test_user
auth.add_user("test_user1", "password")
auth.add_user("test_user2", "password")
self.assertNotEqual(
cfg.users["test_user1"]["passphrase"],
cfg.users["test_user2"]["passphrase"]
)
if __name__ == "__main__":
unittest.main()