def create_user_and_session(self): user = BaseUser(**self.credentials, active=True, admin=True, superuser=True) user.save().run_sync() SessionsBase.create_session_sync(user_id=user.id)
def create(): """ Create a new user. """ username = get_username() email = get_email() password = get_password() confirmed_password = get_confirmed_password() if not password == confirmed_password: sys.exit("Passwords don't match!") if len(password) < 4: sys.exit("The password is too short") is_admin = get_is_admin() is_superuser = get_is_superuser() is_active = get_is_active() user = BaseUser( username=username, password=password, admin=is_admin, email=email, active=is_active, superuser=is_superuser, ) user.save().run_sync() print(f"Created User {user.id}")
def test_update_password(self): username = "******" password = "******" email = "*****@*****.**" user = BaseUser(username=username, password=password, email=email) user.save().run_sync() authenticated = BaseUser.login_sync(username, password) self.assertTrue(authenticated is not None) # Test success new_password = "******" BaseUser.update_password_sync(username, new_password) authenticated = BaseUser.login_sync(username, new_password) self.assertTrue(authenticated is not None) # Test ultra long password malicious_password = secrets.token_urlsafe(1000) with self.assertRaises(ValueError) as manager: BaseUser.update_password_sync(username, malicious_password) self.assertEqual( manager.exception.__str__(), "The password is too long.", )
def test_login_success(self): user = BaseUser(**self.credentials) user.save().run_sync() client = TestClient(APP) response = client.post("/", json=self.credentials) self.assertTrue(response.status_code == 200) self.assertTrue("token" in response.json())
def test_long_password_error(self): with self.assertRaises(ValueError) as manager: BaseUser.create_user_sync( username="******", password="******" * (BaseUser._max_password_length + 1), ) self.assertEqual(manager.exception.__str__(), "The password is too long.")
def test_secret(self): """ Make sure that secret fields are omitted from the response when requested. """ user = BaseUser(username="******", password="******") user.save().run_sync() user_dict = BaseUser.select(exclude_secrets=True).first().run_sync() self.assertTrue("password" not in user_dict.keys())
def test_create(self, *args, **kwargs): user = BaseUser(username="******", password="******") user.save().run_sync() change_password() self.assertTrue( BaseUser.login_sync(username="******", password="******") is not None )
def test_login_success(self): user = BaseUser(**self.credentials) user.save().run_sync() token = TokenAuth.create_token_sync(user_id=user.id) client = TestClient(APP) response = client.post("/", json=self.credentials) self.assertTrue(response.status_code == 200) self.assertTrue(response.json()["token"] == token)
def test_sucess(self): provider = PiccoloTokenAuthProvider() user = BaseUser(**self.credentials) user.save().run_sync() token = TokenAuth.create_token_sync(user_id=user.id) queried_user = run_sync(provider.get_user(token)) self.assertEqual(user.username, queried_user.user["username"])
def test_login_failure(self): user = BaseUser(**self.credentials) user.save().run_sync() client = TestClient(APP) with self.assertRaises(HTTPException): response = client.post("/", json={ "username": "******", "password": "******" }) self.assertTrue(response.status_code == 401)
def setUp(self): BaseUser.create_table(if_not_exists=True).run_sync() BaseUser( username="******", password="******", first_name="Bob", last_name="Jones", email="*****@*****.**", active=False, admin=False, superuser=False, ).save().run_sync()
def test_login(self, logger: MagicMock): username = "******" password = "******" email = "*****@*****.**" user = BaseUser(username=username, password=password, email=email) user.save().run_sync() # Test correct password authenticated = BaseUser.login_sync(username, password) self.assertTrue(authenticated == user.id) # Test incorrect password authenticated = BaseUser.login_sync(username, "blablabla") self.assertTrue(authenticated is None) # Test ultra long password malicious_password = secrets.token_urlsafe(1000) authenticated = BaseUser.login_sync(username, malicious_password) self.assertTrue(authenticated is None) self.assertEqual( logger.method_calls, [call.warning("Excessively long password provided.")], ) # Test ulta long username logger.reset_mock() malicious_username = secrets.token_urlsafe(1000) authenticated = BaseUser.login_sync(malicious_username, password) self.assertTrue(authenticated is None) self.assertEqual( logger.method_calls, [call.warning("Excessively long username provided.")], )
def test_hashed_password_error(self, logger: MagicMock): with self.assertRaises(ValueError) as manager: BaseUser.create_user_sync(username="******", password="******") self.assertEqual(manager.exception.__str__(), "Do not pass a hashed password.") self.assertEqual( logger.method_calls, [ call.warning( "Tried to create a user with an already hashed password.") ], )
def test_create_user_table(self): """ Make sure the table can be created. """ exception = None try: BaseUser.create_table().run_sync() except Exception as e: exception = e else: BaseUser.alter().drop_table().run_sync() if exception: raise exception self.assertFalse(exception)
def test_login(self): username = "******" password = "******" email = "*****@*****.**" user = BaseUser(username=username, password=password, email=email) save_query = user.save() save_query.run_sync() authenticated = asyncio.run(BaseUser.login(username, password)) self.assertTrue(authenticated is not None) authenticated = asyncio.run(BaseUser.login(username, "blablabla")) self.assertTrue(not authenticated)
def create( username: t.Optional[str] = None, email: t.Optional[str] = None, password: t.Optional[str] = None, is_admin: t.Optional[bool] = None, is_superuser: t.Optional[bool] = None, is_active: t.Optional[bool] = None, ): """ Create a new user. """ username = get_username() if username is None else username email = get_email() if email is None else email if password is None: password = get_password() confirmed_password = get_confirmed_password() if password != confirmed_password: sys.exit("Passwords don't match!") is_admin = get_is_admin() if is_admin is None else is_admin is_superuser = get_is_superuser() if is_superuser is None else is_superuser is_active = get_is_active() if is_active is None else is_active user = BaseUser.create_user_sync( username=username, password=password, admin=is_admin, email=email, active=is_active, superuser=is_superuser, ) print(f"Created User {user.id}")
def test_create(self, *args, **kwargs): create() self.assertTrue(BaseUser.exists().where( (BaseUser.admin == True) # noqa: E712 & (BaseUser.username == "bob123") & (BaseUser.email == "*****@*****.**")).run_sync())
def test_create_user_from_fixture(self): the_data = { "id": 2, "username": "", "password": "******" "446b93ed5b$c862974665ccc25b334ed42fa7e96a41" "04d5ddff0c2e56e0e5b1d0efc67e9d03", "first_name": "", "last_name": "", "email": "", "active": False, "admin": False, "superuser": False, "last_login": None, } user = BaseUser.from_dict(the_data) self.assertIsInstance(user, BaseUser) self.assertEqual(user.password, the_data["password"])
def change_password(): """ Change a user's password. """ username = get_username() password = get_password() confirmed_password = get_confirmed_password() if not password == confirmed_password: sys.exit("Passwords don't match!") BaseUser.update_password_sync(user=username, password=password) print(f"Updated password for {username}") print( "If using session auth, we recommend invalidating this user's session." )
async def register_user(user: UserModelIn): user = BaseUser(**user.__dict__) if (await BaseUser.exists().where(BaseUser.email == user.email).run() or await BaseUser.exists().where(BaseUser.username == user.username ).run()): raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="User with that email or username already exists.", ) await user.save().run() return UserModelOut(**user.__dict__)
def get(self, request): data = (SessionsBase.select(SessionsBase.user_id).where( SessionsBase.token == request.cookies.get( "id")).first().run_sync()) if data: session_user = (BaseUser.select( BaseUser.username).where(BaseUser._meta.primary_key == data["user_id"]).first().run_sync()) return PlainTextResponse(f"hello {session_user['username']}") else: return PlainTextResponse("hello world")
def test_register_user_already_exist(self): """ Check that a user who already exists cannot register. """ client = TestClient(APP) BaseUser( username="******", email="*****@*****.**", password="******" ).save().run_sync() response = client.post("/register/", json=self.register_credentials) self.assertEqual(response.status_code, 422) self.assertEqual( response.content, b"User with email or username already exists." )
def test_update_password(self): username = "******" password = "******" email = "*****@*****.**" user = BaseUser(username=username, password=password, email=email) user.save().run_sync() authenticated = BaseUser.login_sync(username, password) self.assertTrue(authenticated is not None) new_password = "******" BaseUser.update_password_sync(username, new_password) authenticated = BaseUser.login_sync(username, new_password) self.assertTrue(authenticated is not None)
def test_non_admin(self): """ Non-admin users should be rejected by the middleware, if configured that way. """ client = TestClient(APP) BaseUser(**self.credentials, active=True, admin=False, superuser=False).save().run_sync() response = client.post("/login/", json=self.credentials) self.assertTrue(response.status_code == 303) # Make a request using the session - it should get rejected. response = client.get("/secret/") self.assertTrue(response.status_code == 400) self.assertEqual(response.content, b"Admin users only")
def test_login_success(self): """ Make sure a user with the correct permissions can access the protected endpoint. """ client = TestClient(APP) BaseUser(**self.credentials, active=True, admin=True, superuser=True).save().run_sync() response = client.post("/login/", json=self.credentials) self.assertTrue(response.status_code == 303) self.assertTrue("id" in response.cookies.keys()) response = client.get("/secret/") self.assertTrue(response.status_code == 200) self.assertEqual(response.content, b"top secret")
def test_hooks(self): # TODO Replace these with mocks ... def pre_login_test(username): assert isinstance(username, str) async def pre_login_test_async(username): assert isinstance(username, str) def login_success_test(username, user_id): assert isinstance(username, str) assert isinstance(user_id, int) async def login_success_test_async(username, user_id): assert isinstance(username, str) assert isinstance(user_id, int) def login_failure_test(username): assert isinstance(username, str) def login_failure_test_async(username): assert isinstance(username, str) router = Router( routes=[ Route( "/login/", session_login( hooks=LoginHooks( pre_login=[pre_login_test, pre_login_test_async], login_success=[ login_success_test, login_success_test_async, ], login_failure=[ login_failure_test, login_failure_test_async, ], ) ), ), ] ) app = ExceptionMiddleware(router) BaseUser(**self.credentials, active=True).save().run_sync() client = TestClient(app) client.post("/login/", json=self.credentials)
def test_create_with_arguments(self, *args, **kwargs): arguments = { "username": "******", "email": "*****@*****.**", "password": "******", "is_admin": True, "is_superuser": True, "is_active": True, } create(**arguments) self.assertTrue( BaseUser.exists().where((BaseUser.admin == True) # noqa: E712 & (BaseUser.username == "bob123") & (BaseUser.email == "*****@*****.**") & (BaseUser.superuser.eq(True)) & (BaseUser.active.eq(True))).run_sync())
def test_inactive_user(self): """ Inactive users should be rejected by the middleware, if configured that way. """ client = TestClient(APP) BaseUser(**self.credentials, active=False, admin=True, superuser=True).save().run_sync() response = client.post("/login/", json=self.credentials) # Currently the login is successful if the user is inactive - this # should change in the future. self.assertTrue(response.status_code == 303) # Make a request using the session - it should get rejected. response = client.get("/secret/") self.assertTrue(response.status_code == 400) self.assertEqual(response.content, b"Active users only")
def test_change_password_missing_fields(self): """ Make sure all fields on the form are filled out. """ client = TestClient(APP) BaseUser( **self.credentials, active=True, admin=True, superuser=True ).save().run_sync() response = client.post("/login/", json=self.credentials) client = TestClient(APP) response = client.post( "/change-password/", cookies={"id": f"{response.cookies.values()[0]}"}, json={}, ) self.assertEqual(response.status_code, 422) self.assertEqual( response.content, b"Form is invalid. Missing one or more fields." )
def test_correct_current_password(self): """ Make sure a POST request to `change_password` works. """ client = TestClient(APP) BaseUser( **self.credentials, active=True, admin=True, superuser=True ).save().run_sync() response = client.post("/login/", json=self.credentials) client = TestClient(APP) response = client.post( "/change-password/", cookies={"id": f"{response.cookies.values()[0]}"}, json={ "current_password": f"{self.credentials['password']}", "new_password": "******", "confirm_new_password": "******", }, ) self.assertEqual(response.status_code, 303)