def test_dump_and_load(logger, mongodb): """Test the dump and loading of the user 'universe'. """ assert user.count() == 0 assert user.dump() == [] username = u'andrés.bolívar' display_name = u'Andrés Plácido Bolívar' email = u'andrés.bolí[email protected]' data = [ { "username": "******", "oauth_tokens": { "googleauth": { "request_token": "1234567890" } }, "display_name": "Bobby", "phone": "12121212", "cats": "big", "teatime": 1, "_id": "user-2719963b00964c01b42b5d81c998fd05", "email": "*****@*****.**", "password_hash": pwtools.hash_password('11amcoke') }, { "username": username.encode('utf-8'), "display_name": display_name.encode('utf-8'), "phone": "", "_id": "user-38ed1d2903344702b30bb951916aaf1c", "email": email.encode('utf-8'), "password_hash": pwtools.hash_password('$admintime$') } ] user.load(data) assert user.count() == 2 item2 = user.get('bob.sprocket') user_dict = data[0] assert item2['username'] == user_dict['username'] assert item2['display_name'] == user_dict['display_name'] assert item2['email'] == user_dict['email'] assert item2['phone'] == user_dict['phone'] assert item2['oauth_tokens'] == user_dict['oauth_tokens'] assert item2['cats'] == 'big' assert item2['teatime'] == 1 # Test the unicode name as still good: item1 = user.get(username) user_dict = data[1] assert item1['username'] == username assert item1['display_name'] == display_name assert item1['email'] == email assert item1['phone'] == user_dict['phone']
def test_UserLoadingAndDumping(logger, mongodb, user_svc): """Test the rest client's ping of the user service. """ assert not len(user_svc.api.user.all()) assert user_svc.api.dump() == [] username = u"andrés.bolívar" display_name = u"Andrés Plácido Bolívar" email = u"andrés.bolí[email protected]" data = [ { "username": "******", "oauth_tokens": {"googleauth": {"request_token": "1234567890"}}, "display_name": "Bobby", "phone": "12121212", "cats": "big", "teatime": 1, "_id": "user-2719963b00964c01b42b5d81c998fd05", "email": "*****@*****.**", "password_hash": pwtools.hash_password("11amcoke"), }, { "username": username.encode("utf-8"), "display_name": display_name.encode("utf-8"), "phone": "", "_id": "user-38ed1d2903344702b30bb951916aaf1c", "email": email.encode("utf-8"), "password_hash": pwtools.hash_password("$admintime$"), }, ] user_svc.api.load(data) assert len(user_svc.api.user.all()) == 2 item2 = user_svc.api.user.get("bob.sprocket") user_dict = data[0] assert item2["username"] == user_dict["username"] assert item2["display_name"] == user_dict["display_name"] assert item2["email"] == user_dict["email"] assert item2["phone"] == user_dict["phone"] assert item2["oauth_tokens"] == user_dict["oauth_tokens"] assert item2["cats"] == "big" assert item2["teatime"] == 1 # Test the unicode name as still good: item1 = user_svc.api.user.get(username) user_dict = data[1] assert item1["username"] == username assert item1["display_name"] == display_name assert item1["email"] == email assert item1["phone"] == user_dict["phone"]
def testExtraField(self): """Test the arbitrary dic that can be used to store useful fields per user. """ username = '******' plain_pw = '1234567890' self.assertEquals(user.count(), 0) self.assertEquals(user.find(username=username), []) user_dict = dict(username=username, password=plain_pw, display_name='Bob Sprocket', email='*****@*****.**', phone='9876543210') item1 = user.add(**user_dict) # Make sure I cannot add the same username again: self.assertRaises(user.UserPresentError, user.add, **user_dict) self.assertEquals(user.find(username=username), [item1]) self.assertEquals(user.has(username), True) self.assertEquals(user.count(), 1) item2 = user.get(username) self.assertEquals(item2.username, user_dict['username']) self.assertEquals(item2.display_name, user_dict['display_name']) self.assertTrue(item2.validate_password(plain_pw)) self.assertFalse(item2.validate_password("not the right one")) self.assertEquals(item2.email, user_dict['email']) self.assertEquals(item2.phone, user_dict['phone']) self.assertEquals(item2.extra, {}) # Now update all the user fields that can be changed # and add some extra data to the arbitrary fields: # freeform_data = dict( # Some pretend googleservice oauth data: googleauth=dict(request_token="1234567890", )) user_dict = dict( username=username, password_hash=pwtools.hash_password("ifidexmemwb"), display_name='Bobby', email='*****@*****.**', phone='12121212', extra=freeform_data, ) user.update(**user_dict) item2 = user.get(username) self.assertEquals(item2.username, user_dict['username']) self.assertEquals(item2.display_name, user_dict['display_name']) self.assertTrue(item2.validate_password("ifidexmemwb")) self.assertFalse(item2.validate_password("not the right one")) self.assertEquals(item2.email, user_dict['email']) self.assertEquals(item2.phone, user_dict['phone']) self.assertEquals(item2.extra, freeform_data)
def test_validate_password(logger, mongodb): assert user.count() == 0 assert user.dump() == [] username = u'andrés.bolívar' display_name = u'Andrés Plácido Bolívar' email = u'andrés.bolí[email protected]' data = [ { "username": "******", "oauth_tokens": { "googleauth": { "request_token": "1234567890" } }, "display_name": "Bobby", "phone": "12121212", "cats": "big", "teatime": 1, "_id": "user-2719963b00964c01b42b5d81c998fd05", "email": "*****@*****.**", "password_hash": pwtools.hash_password('11amcoke') }, { "username": username.encode('utf-8'), "display_name": display_name.encode('utf-8'), "phone": "", "_id": "user-38ed1d2903344702b30bb951916aaf1c", "email": email.encode('utf-8'), "password_hash": pwtools.hash_password('$admintime$') } ] user.load(data) assert user.validate_password('bob.sprocket', '11amcoke') is True assert user.validate_password('bob.sprocket', 'incorrect') is False assert user.validate_password(username, '11amcoke') is False assert user.validate_password(username, '$admintime$') is True
def test_password_change(logger, mongodb, user_svc): """Test changing a user's password. """ username = "******" plain_pw = "123456" user = dict(username=username, password_hash=pwtools.hash_password(plain_pw), email="*****@*****.**") user_svc.api.user.add(user) result = user_svc.api.user.authenticate(username, plain_pw) assert result is True # Change and test the old password is no longer valid. new_plain_pw = "654321" user_svc.api.user.update(dict(username=username, password_hash=pwtools.hash_password(new_plain_pw))) username = user["username"] assert user_svc.api.user.authenticate(username, plain_pw) is False # Now test that password has changed. username = user["username"] assert user_svc.api.user.authenticate(username, new_plain_pw) is True
def __init__( self, username, password=None, password_hash=None, display_name='', email='', phone='', extra={} ): """Create a User instance in the database. :param username: This is the user's unique name used to log into the system. :param password: This is the plain text password, which will be hashed and stored. The plain password is NOT stored. :param password_hash: This is the prehashed password to be stored. If no password and password_hash is given ValueError will be raised as one of the fields must be used. :param display_name: The text used instead of the unique username (empty by default). :param email: An email address for the user (empty by default). :param phone: A phone number the user (empty by default). :param extra: A python dict containing arbitrary, JSON encodable, data. """ self.id = guid() self.username = username # One of these must be provided: if not password and not password_hash: raise ValueError("No password or password_hash provided!") # A handy conversion saving the end user from having to do this: if password: self.password_hash = pwtools.hash_password(password) else: self.password_hash = password_hash self.display_name = display_name self.email = email self.phone = phone self.extra = extra
def test_user_recovery_for_access_token(logger, mongodb): """Test the recover a user's access_secret based on a given access_token. """ assert user.count() == 0 assert user.dump() == [] username = '******' access_token = ( "eyJleHBpcmVzIjogMTAsICJzYWx0IjogImMyNzZjMCIsICJpZGVudGl0eSI6ICJib2Iif" "QtSy56A7SfLFayHdmuWdwZDBZESKvDCVAIxwHmYqg1wd8LOn12djG_thZg26TTzknKVqT" "GmkOs5hs-B-zSfjVU=" ) access_secret = ( "cf25474cda623fe4cb9cebdbb0c328d44ec33d883d27b8e5dc7d62de2247296fe85e7" "3dc6fb2d6cfe19f2c107676b52070010b1f932c6f25f74f308fe19c09f3" ) data = [ { "username": username, "tokens": { access_token: { "access_secret": access_secret } }, "display_name": "Bobby", "phone": "12121212", "_id": "user-2719963b00964c01b42b5d81c998fd05", "email": "*****@*****.**", "password_hash": pwtools.hash_password('11amcoke') }, ] user.load(data) # Recover the user's secret given the access_token: found = user.secret_for_access_token(access_token) assert found == access_secret # If the token is unknown the nothing will be returned. assert user.secret_for_access_token('fake-token') is None
def testExtraField(self): """Test the arbitrary dic that can be used to store useful fields per user. """ username = '******' plain_pw = '1234567890' self.assertEquals(user.count(), 0) self.assertEquals(user.find(username=username), []) user_dict = dict( username=username, password=plain_pw, display_name='Bob Sprocket', email='*****@*****.**', phone='9876543210' ) item1 = user.add(**user_dict) # Make sure I cannot add the same username again: self.assertRaises(user.UserPresentError, user.add, **user_dict) self.assertEquals(user.find(username=username), [item1]) self.assertEquals(user.has(username), True) self.assertEquals(user.count(), 1) item2 = user.get(username) self.assertEquals(item2.username, user_dict['username']) self.assertEquals(item2.display_name, user_dict['display_name']) self.assertTrue(item2.validate_password(plain_pw)) self.assertFalse(item2.validate_password("not the right one")) self.assertEquals(item2.email, user_dict['email']) self.assertEquals(item2.phone, user_dict['phone']) self.assertEquals(item2.extra, {}) # Now update all the user fields that can be changed # and add some extra data to the arbitrary fields: # freeform_data = dict( # Some pretend googleservice oauth data: googleauth=dict( request_token="1234567890", ) ) user_dict = dict( username=username, password_hash=pwtools.hash_password("ifidexmemwb"), display_name='Bobby', email='*****@*****.**', phone='12121212', extra=freeform_data, ) user.update(**user_dict) item2 = user.get(username) self.assertEquals(item2.username, user_dict['username']) self.assertEquals(item2.display_name, user_dict['display_name']) self.assertTrue(item2.validate_password("ifidexmemwb")) self.assertFalse(item2.validate_password("not the right one")) self.assertEquals(item2.email, user_dict['email']) self.assertEquals(item2.phone, user_dict['phone']) self.assertEquals(item2.extra, freeform_data)
def test_user_management(logger, mongodb, user_svc): """Test the REST based interface to add/remove/update users. """ user = dict( username="******", password_hash=pwtools.hash_password("123456"), display_name="Bob Sprocket", email="*****@*****.**", phone="1234567890", # extra={}, ) bob = user_svc.api.user.add(user) assert bob["username"] == user["username"] assert bob["display_name"] == user["display_name"] assert bob["email"] == user["email"] assert bob["phone"] == user["phone"] # assert (bob['extra'] == user['extra'] # Check the unique user id is in the bob dict. Its value is generated # by the server. assert "_id" in bob # No plain text password is stored or sent over the wire: assert "password_hash" in bob bob = user_svc.api.user.get(user["username"]) assert bob["username"] == user["username"] assert bob["display_name"] == user["display_name"] assert bob["email"] == user["email"] assert bob["phone"] == user["phone"] # assert bob['extra'] == user['extra'] assert "_id" in bob # Check I can't add the same user a second time: with pytest.raises(userdata.UserServiceError): user_svc.api.user.add(user) # Test verifcation of the password: plain_pw = "123456" username = user["username"] assert user_svc.api.user.authenticate(username, plain_pw) is True plain_pw = "not the correct password" username = user["username"] assert user_svc.api.user.authenticate(username, plain_pw) is False # Try updating all user's information that can be changed: user = dict( username=username, password_hash=pwtools.hash_password("654321"), display_name="Sprokety Bob", email="*****@*****.**", phone="0987654321", # extra={"a": 1}, ) user_svc.api.user.update(user) bob = user_svc.api.user.get(user["username"]) assert bob["username"] == user["username"] assert bob["display_name"] == user["display_name"] assert bob["email"] == user["email"] assert bob["phone"] == user["phone"] # assert bob['extra'] == user['extra'] # Now delete the user's account from the system. user_svc.api.user.remove(username) with pytest.raises(userdata.UserServiceError): user_svc.api.user.remove(username)
def test_hash_then_unhash(): plain_password = "******" hashed_pw = pwtools.hash_password(plain_password) assert pwtools.validate_password(plain_password, hashed_pw)
def test_hash_then_unhash_fail_unicode_other(): plain_password = u"manÃna123" hashed_pw = pwtools.hash_password(plain_password) assert not pwtools.validate_password("not the password", hashed_pw)
def test_hash_then_unhash_fail_unicode(): plain_password = u"manÃna123" hashed_pw = pwtools.hash_password(plain_password) assert not pwtools.validate_password(u"Àôøôò°", hashed_pw)
def test_hash_then_unhash_unicode(): plain_password = u"manÃna123" hashed_pw = pwtools.hash_password(plain_password) assert pwtools.validate_password(plain_password, hashed_pw)
def test_hash_then_unhash_leading_and_trailing_space(): plain_password = "******" hashed_pw = pwtools.hash_password(plain_password) assert pwtools.validate_password(plain_password, hashed_pw)
def update(**user): """Called to update the details of an exiting user on the system. This handles the 'new_password' field before passing on to the generic update. Only password can be changed at the moment. """ log = get_log('update') log.debug("Given user <%s> to update." % user) update_data = {} current = get(user['username']) if "new_password" in user: new_password = user['new_password'] user.pop('new_password') # Set the new password hash to store, replacing the current one: new_password = pwtools.hash_password(new_password) update_data['password_hash'] = new_password if "display_name" in user: update_data['display_name'] = user['display_name'] if "new_username" in user: new_username = user['new_username'] if not has(user['new_username']): update_data['username'] = new_username else: raise UserPresentError( "Cannot rename to username <%s> as it is used." % new_username ) if "password_hash" in user: update_data['password_hash'] = user['password_hash'] if "email" in user: update_data['email'] = user['email'] if "phone" in user: update_data['phone'] = user['phone'] if "extra" in user: # I need to use the special extra property to correct handle conversion # to valid JSON that can be stored. Then set the raw field that the # low level update will set. current.extra = user['extra'] # should be valid "{}" or "{..data..}" at this point: update_data['json_extra'] = current.json_extra # commits handled elsewhere: update_data['no_commit'] = True #print "\n\nupdate_data:\n%s\n\n" % update_data g_update(current, **update_data) log.debug("<%s> updated OK." % user['username']) # Return the updated user details: return get(user['username'])