mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-05-27 10:44:33 +00:00
Update tests for auth module, and fix some bugs discovered in auth module.
This commit is contained in:
parent
2abe8559e5
commit
f7ad1089a5
@ -9,22 +9,30 @@
|
|||||||
import cherrypy
|
import cherrypy
|
||||||
import urllib
|
import urllib
|
||||||
from passlib.hash import bcrypt
|
from passlib.hash import bcrypt
|
||||||
|
from passlib.exc import PasswordSizeError
|
||||||
import cfg
|
import cfg
|
||||||
import random
|
import random
|
||||||
import time
|
import time
|
||||||
|
from model import User
|
||||||
|
|
||||||
cfg.session_key = '_cp_username'
|
cfg.session_key = '_cp_username'
|
||||||
|
|
||||||
def add_user(username, passphrase, name='', email='', expert=False):
|
def add_user(username, passphrase, name='', email='', expert=False):
|
||||||
|
"""Add a new user with specified username and passphrase.
|
||||||
|
"""
|
||||||
error = None
|
error = None
|
||||||
if not username: error = "Must specify a username!"
|
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:
|
if error is None:
|
||||||
# hash the password whether the user exists, to foil timing
|
# hash the password whether the user exists, to foil timing
|
||||||
# side-channel attacks
|
# 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():
|
if username in cfg.users.get_all():
|
||||||
error = "User already exists!"
|
error = "User already exists!"
|
||||||
else:
|
else:
|
||||||
@ -38,7 +46,7 @@ def add_user(username, passphrase, name='', email='', expert=False):
|
|||||||
'salt':pass_hash[7:29], # for bcrypt
|
'salt':pass_hash[7:29], # for bcrypt
|
||||||
}
|
}
|
||||||
new_user = User(di)
|
new_user = User(di)
|
||||||
cfg.users.set(username,newuser)
|
cfg.users.set(username,new_user)
|
||||||
|
|
||||||
if error:
|
if error:
|
||||||
cfg.log(error)
|
cfg.log(error)
|
||||||
@ -55,13 +63,19 @@ def check_credentials(username, passphrase):
|
|||||||
cfg.log(error)
|
cfg.log(error)
|
||||||
return 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
|
# hash the password whether the user exists, to foil timing
|
||||||
# side-channel attacks
|
# 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:
|
if u is None or u['passphrase'] != pass_hash:
|
||||||
error = "Bad user-name or password."
|
error = "Bad user-name or password."
|
||||||
|
|||||||
@ -26,45 +26,43 @@ class Auth(unittest.TestCase):
|
|||||||
cfg.users.remove(user[0])
|
cfg.users.remove(user[0])
|
||||||
cfg.users.close()
|
cfg.users.close()
|
||||||
|
|
||||||
def test_password_check(self):
|
def test_add_user(self):
|
||||||
self.add_user("test_user", "password")
|
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.assertIsNone(auth.check_credentials("test_user", "password"))
|
||||||
self.assertIsNotNone(auth.check_credentials("test_user", "wrong"))
|
self.assertIsNotNone(auth.check_credentials("test_user", "wrong"))
|
||||||
|
|
||||||
def test_salt_check(self):
|
def test_nonexistent_user(self):
|
||||||
test_user = self.add_user("test_user", "password", "abcdefghijklmnopqrstuv")
|
|
||||||
self.assertIsNotNone(auth.check_credentials("test_user", "password"))
|
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):
|
def test_salt_is_random(self):
|
||||||
test_user1 = self.add_user("test_user1", "password")
|
auth.add_user("test_user1", "password")
|
||||||
test_user2 = self.add_user("test_user2", "password")
|
auth.add_user("test_user2", "password")
|
||||||
self.assertNotEqual(test_user1["salt"], test_user2["salt"])
|
self.assertNotEqual(
|
||||||
|
cfg.users["test_user1"]["salt"],
|
||||||
|
cfg.users["test_user2"]["salt"]
|
||||||
|
)
|
||||||
|
|
||||||
def test_hash_is_random(self):
|
def test_hash_is_random(self):
|
||||||
test_user1 = self.add_user("test_user1", "password")
|
auth.add_user("test_user1", "password")
|
||||||
test_user2 = self.add_user("test_user2", "password")
|
auth.add_user("test_user2", "password")
|
||||||
self.assertNotEqual(test_user1["passphrase"], test_user2["passphrase"])
|
self.assertNotEqual(
|
||||||
|
cfg.users["test_user1"]["passphrase"],
|
||||||
# set fake_salt if you want to store an invalid salt
|
cfg.users["test_user2"]["passphrase"]
|
||||||
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
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user