# Path: amivapi/auth/sessions.py
# def verify_password(user, plaintext):
#     """Check password of user, rehash if necessary.
# 
#     It is possible that the password is None, e.g. if the user is authenticated
#     via LDAP. In this case default to "not verified".
# 
#     Args:
#         user (dict): the user in question.
#         plaintext (string): password to check
# 
#     Returns:
#         bool: True if password matches. False if it doesn't or if there is no
#             password set and/or provided.
#     """
#     password_context = app.config['PASSWORD_CONTEXT']
# 
#     if (plaintext is None) or (user['password'] is None):
#         return False
# 
#     is_valid = password_context.verify(plaintext, user['password'])
# 
#     if is_valid and password_context.needs_update(user['password']):
#         # update password - hook will handle hashing
#         update = {'password': plaintext}
#         with admin_permissions():
#             patch_internal("users", payload=update, _id=user['_id'])
#     return is_valid
# 
# Path: amivapi/tests/utils.py
# class WebTest(unittest.TestCase, FixtureMixin):
#     """Base test class for tests against the full WSGI stack.
# 
#     Inspired by eve standard testing class.
#     """
# 
#     # Test Config overwrites
#     test_config = {
#         'MONGO_DBNAME': 'test_amivapi',
#         'MONGO_USERNAME': 'test_user',
#         'MONGO_PASSWORD': 'test_pw',
#         'API_MAIL': 'api@test.ch',
#         'SMTP_SERVER': '',
#         'TESTING': True,
#         'DEBUG': True,   # This makes eve's error messages more helpful
#         'LDAP_USERNAME': None,  # LDAP test require special treatment
#         'LDAP_PASSWORD': None,  # LDAP test require special treatment
#         'SENTRY_DSN': None,
#         'SENTRY_ENVIRONMENT': None,
#         'PASSWORD_CONTEXT': CryptContext(
#             schemes=["pbkdf2_sha256"],
#             pbkdf2_sha256__default_rounds=10,
#             # min_rounds is used to determine if a hash needs to be upgraded
#             pbkdf2_sha256__min_rounds=8,
#         )
#     }
# 
#     def setUp(self, **extra_config):
#         """Set up the testing client and database connection.
# 
#         self.api will be a flask TestClient to make requests
#         self.db will be a MongoDB database
#         """
#         super().setUp()
# 
#         # In 3.2, assertItemsEqual was replaced by assertCountEqual
#         # Make assertItemsEqual work in tests for py3 as well
#         if sys.version_info >= (3, 2):
#             self.assertItemsEqual = self.assertCountEqual
# 
#         # create eve app and test client
#         config = {}
#         config.update(self.test_config)
#         config.update(extra_config)
#         self.app = bootstrap.create_app(**config)
#         self.app.response_class = TestResponse
#         self.app.test_client_class = TestClient
#         self.app.test_mails = []
#         self.api = self.app.test_client()
# 
#         # Create a separate mongo connection and db reference for tests
#         self.connection = MongoClient(host=self.app.config['MONGO_HOST'],
#                                       port=self.app.config['MONGO_PORT'])
#         self.db = self.connection[self.app.config['MONGO_DBNAME']]
#         self.db.authenticate(name=self.app.config['MONGO_USERNAME'],
#                              password=self.app.config['MONGO_PASSWORD'],
#                              source=self.app.config['MONGO_DBNAME'])
# 
#     def tearDown(self):
#         """Tear down after testing."""
#         # delete testing database
#         self.connection.drop_database(self.test_config['MONGO_DBNAME'])
#         # close database connection
#         self.connection.close()
# 
#     # Shortcuts to get a token
#     counter = count()
# 
#     def get_user_token(self, user_id, created=None):
#         """Create session for a user and return a token.
# 
#         Args:
#             user_id (str): user_id as string.
# 
#         Returns:
#             str: Token that can be used to authenticate user.
#         """
#         if created is None:
#             created = datetime.now(timezone.utc)
# 
#         token = "test_token_" + str(next(self.counter))
#         self.db['sessions'].insert_one({u'user': ObjectId(user_id),
#                                         u'token': token,
#                                         u'_created': created})
#         return token
# 
#     def get_root_token(self):
#         """The root password is the root token.
# 
#         Returns:
#             str: Token for the root user
#         """
#         return ROOT_PASSWORD


from bson import ObjectId
from passlib.context import CryptContext
from passlib.hash import pbkdf2_sha256
from amivapi.auth.sessions import verify_password
from amivapi.tests.utils import WebTest
        password = u"some-really-secure-password"
        user = self.new_object('users', nethz=u"abc",
                               email="user@amiv",
                               password=password)
        user_id = str(user['_id'])

        bad_data = [
            # Missing data
            {'username': user_id},
            {'password': password},
            # Invalid user
            {'username': None,
             'password': password},
            {'username': '',
             'password': password},
            # Invalid password
            {'username': user_id,
             'password': None}
        ]

        for data in bad_data:
            self.api.post("/sessions",
                          data=data,
                          status_code=422)

    def test_invalid_token(self):
        """Try to do a request using invalid token."""
        self.api.get("/users", token=u"There is no token!", status_code=401)



# Path: amivapi/auth/sessions.py
# def verify_password(user, plaintext):
#     """Check password of user, rehash if necessary.
# 
#     It is possible that the password is None, e.g. if the user is authenticated
#     via LDAP. In this case default to "not verified".
# 
#     Args:
#         user (dict): the user in question.
#         plaintext (string): password to check
# 
#     Returns:
#         bool: True if password matches. False if it doesn't or if there is no
#             password set and/or provided.
#     """
#     password_context = app.config['PASSWORD_CONTEXT']
# 
#     if (plaintext is None) or (user['password'] is None):
#         return False
# 
#     is_valid = password_context.verify(plaintext, user['password'])
# 
#     if is_valid and password_context.needs_update(user['password']):
#         # update password - hook will handle hashing
#         update = {'password': plaintext}
#         with admin_permissions():
#             patch_internal("users", payload=update, _id=user['_id'])
#     return is_valid
# 
# Path: amivapi/tests/utils.py
# class WebTest(unittest.TestCase, FixtureMixin):
#     """Base test class for tests against the full WSGI stack.
# 
#     Inspired by eve standard testing class.
#     """
# 
#     # Test Config overwrites
#     test_config = {
#         'MONGO_DBNAME': 'test_amivapi',
#         'MONGO_USERNAME': 'test_user',
#         'MONGO_PASSWORD': 'test_pw',
#         'API_MAIL': 'api@test.ch',
#         'SMTP_SERVER': '',
#         'TESTING': True,
#         'DEBUG': True,   # This makes eve's error messages more helpful
#         'LDAP_USERNAME': None,  # LDAP test require special treatment
#         'LDAP_PASSWORD': None,  # LDAP test require special treatment
#         'SENTRY_DSN': None,
#         'SENTRY_ENVIRONMENT': None,
#         'PASSWORD_CONTEXT': CryptContext(
#             schemes=["pbkdf2_sha256"],
#             pbkdf2_sha256__default_rounds=10,
#             # min_rounds is used to determine if a hash needs to be upgraded
#             pbkdf2_sha256__min_rounds=8,
#         )
#     }
# 
#     def setUp(self, **extra_config):
#         """Set up the testing client and database connection.
# 
#         self.api will be a flask TestClient to make requests
#         self.db will be a MongoDB database
#         """
#         super().setUp()
# 
#         # In 3.2, assertItemsEqual was replaced by assertCountEqual
#         # Make assertItemsEqual work in tests for py3 as well
#         if sys.version_info >= (3, 2):
#             self.assertItemsEqual = self.assertCountEqual
# 
#         # create eve app and test client
#         config = {}
#         config.update(self.test_config)
#         config.update(extra_config)
#         self.app = bootstrap.create_app(**config)
#         self.app.response_class = TestResponse
#         self.app.test_client_class = TestClient
#         self.app.test_mails = []
#         self.api = self.app.test_client()
# 
#         # Create a separate mongo connection and db reference for tests
#         self.connection = MongoClient(host=self.app.config['MONGO_HOST'],
#                                       port=self.app.config['MONGO_PORT'])
#         self.db = self.connection[self.app.config['MONGO_DBNAME']]
#         self.db.authenticate(name=self.app.config['MONGO_USERNAME'],
#                              password=self.app.config['MONGO_PASSWORD'],
#                              source=self.app.config['MONGO_DBNAME'])
# 
#     def tearDown(self):
#         """Tear down after testing."""
#         # delete testing database
#         self.connection.drop_database(self.test_config['MONGO_DBNAME'])
#         # close database connection
#         self.connection.close()
# 
#     # Shortcuts to get a token
#     counter = count()
# 
#     def get_user_token(self, user_id, created=None):
#         """Create session for a user and return a token.
# 
#         Args:
#             user_id (str): user_id as string.
# 
#         Returns:
#             str: Token that can be used to authenticate user.
#         """
#         if created is None:
#             created = datetime.now(timezone.utc)
# 
#         token = "test_token_" + str(next(self.counter))
#         self.db['sessions'].insert_one({u'user': ObjectId(user_id),
#                                         u'token': token,
#                                         u'_created': created})
#         return token
# 
#     def get_root_token(self):
#         """The root password is the root token.
# 
#         Returns:
#             str: Token for the root user
#         """
#         return ROOT_PASSWORD


# Path: amivapi/tests/auth/test_sessions.py
from bson import ObjectId
from passlib.context import CryptContext
from passlib.hash import pbkdf2_sha256
from amivapi.auth.sessions import verify_password
from amivapi.tests.utils import WebTest

        password = u"some-really-secure-password"
        user = self.new_object('users', nethz=u"abc",
                               email="user@amiv",
                               password=password)
        user_id = str(user['_id'])

        bad_data = [
            # Missing data
            {'username': user_id},
            {'password': password},
            # Invalid user
            {'username': None,
             'password': password},
            {'username': '',
             'password': password},
            # Invalid password
            {'username': user_id,
             'password': None}
        ]

        for data in bad_data:
            self.api.post("/sessions",
                          data=data,
                          status_code=422)

    def test_invalid_token(self):
        """Try to do a request using invalid token."""
        self.api.get("/users", token=u"There is no token!", status_code=401)



class PasswordVerificationTest(WebTest):