Esempio n. 1
0
    async def test_change_password(self):
        user_id, password = await self._create_test_user(
            "user", "*****@*****.**")
        _, session_id, _ = await self.user_service.login_user(
            "user", password=password, session_name="session1")
        token = token_for_user(user_id, session_id, self.secret_key)

        headers = {"Authorization": f"Bearer {token}"}

        # check that we cannot change anything without providing the correct password
        resp = await self.client.post(
            f"/api/v1/profile/change_password",
            headers=headers,
            json={
                "old_password": "******",
                "new_password": "******"
            },
        )
        self.assertEqual(400, resp.status)

        resp = await self.client.post(
            f"/api/v1/profile/change_password",
            headers=headers,
            json={
                "old_password": password,
                "new_password": "******"
            },
        )
        self.assertEqual(204, resp.status)

        # check that we can login with the new password
        await self._login("user", "password2")
Esempio n. 2
0
    async def setUpAsync(self) -> None:
        await super().setUpAsync()

        self.test_user_id, password = await self._create_test_user(
            "user1", "*****@*****.**")
        _, session_id, _ = await self.user_service.login_user(
            "user1", password=password, session_name="session1")
        self.jwt_token = token_for_user(self.test_user_id, session_id,
                                        self.secret_key)
Esempio n. 3
0
    async def test_change_email(self):
        username = "******"
        old_email = "*****@*****.**"
        new_email = "*****@*****.**"
        user_id, password = await self._create_test_user(username, old_email)
        _, session_id, _ = await self.user_service.login_user(
            username=username, password=password, session_name="session1")
        token = token_for_user(user_id, session_id, self.secret_key)

        headers = {"Authorization": f"Bearer {token}"}
        resp = await self.client.post(
            f"/api/v1/profile/change_email",
            headers=headers,
            json={
                "email": new_email,
                "password": password
            },
        )
        self.assertEqual(204, resp.status)

        resp = await self.client.post(
            f"/api/v1/profile/change_email",
            headers=headers,
            json={
                "email": new_email,
                "password": "******"
            },
        )
        self.assertEqual(400, resp.status)

        resp = await self.client.get(f"/api/v1/profile", headers=headers)
        self.assertEqual(200, resp.status)
        profile = await resp.json()
        # we still have the old email
        self.assertEqual(old_email, profile["email"])

        # confirm the email change
        # fetch the registration token from the database
        async with self.db_pool.acquire() as conn:
            token = await conn.fetchval(
                "select token from pending_email_change where user_id = $1",
                user_id)
        resp = await self.client.post(f"/api/v1/auth/confirm_email_change",
                                      json={"token": "foobar lol"})
        self.assertEqual(400, resp.status)

        resp = await self.client.post(f"/api/v1/auth/confirm_email_change",
                                      json={"token": str(token)})
        self.assertEqual(204, resp.status)

        # now we have the new email
        resp = await self.client.get(f"/api/v1/profile", headers=headers)
        self.assertEqual(200, resp.status)
        profile = await resp.json()
        # we still have the old email
        self.assertEqual(new_email, profile["email"])
Esempio n. 4
0
    async def test_websocket_notifications(self):
        user_id, password = await self._create_test_user(
            username="******", email="*****@*****.**")
        _, session_id, _ = await self.user_service.login_user(
            "user", password=password, session_name="session1")
        token = token_for_user(user_id,
                               session_id=session_id,
                               secret_key=self.secret_key)

        ws = await self.client.ws_connect("/api/v1/ws")
        self.assertIsNotNone(ws)

        await ws.send_json({
            "type": "subscribe",
            "token": token,
            "data": {
                "subscription_type": "group",
                "element_id": user_id
            },
        })

        await self.expect_ws_message(
            ws,
            {
                "type": "subscribe_success",
                "data": {
                    "element_id": user_id,
                    "subscription_type": "group",
                },
            },
        )

        group_id = await self.group_service.create_group(
            user_id=user_id,
            name="group1",
            description="asdf",
            currency_symbol="€",
            terms="terms...",
        )

        # make sure we receive a notification on the group scope
        await self.expect_ws_message(
            ws,
            {
                "type": "notification",
                "data": {
                    "element_id": user_id,
                    "group_id": group_id,
                    "subscription_type": "group",
                },
            },
        )

        await ws.send_json({
            "type": "subscribe",
            "token": token,
            "data": {
                "subscription_type": "account",
                "element_id": group_id
            },
        })

        await self.expect_ws_message(
            ws,
            {
                "type": "subscribe_success",
                "data": {
                    "element_id": group_id,
                    "subscription_type": "account",
                },
            },
        )

        account_id = await self.account_service.create_account(
            user_id=user_id,
            group_id=group_id,
            type="personal",
            name="group1",
            description="asdf",
        )
        await self.expect_ws_message(
            ws,
            {
                "type": "notification",
                "data": {
                    "element_id": group_id,
                    "account_id": account_id,
                    "subscription_type": "account",
                },
            },
        )

        # subscribe to transaction changes
        await ws.send_json({
            "type": "subscribe",
            "token": token,
            "data": {
                "subscription_type": "transaction",
                "element_id": group_id
            },
        })

        await self.expect_ws_message(
            ws,
            {
                "type": "subscribe_success",
                "data": {
                    "element_id": group_id,
                    "subscription_type": "transaction",
                },
            },
        )

        transaction_id = await self.transaction_service.create_transaction(
            user_id=user_id,
            group_id=group_id,
            type="transfer",
            value=1.2,
            currency_symbol="€",
            currency_conversion_rate=1.0,
            billed_at=date.today(),
            description="asdf",
        )

        await self.expect_ws_message(
            ws,
            {
                "type": "notification",
                "data": {
                    "element_id": group_id,
                    "transaction_id": transaction_id,
                    "subscription_type": "transaction",
                    "deleted": False,
                    "revision_committed": None,
                    "revision_version": 0,
                },
            },
        )

        # subscribe to group invite changes
        await ws.send_json({
            "type": "subscribe",
            "token": token,
            "data": {
                "subscription_type": "group_invite",
                "element_id": group_id
            },
        })

        await self.expect_ws_message(
            ws,
            {
                "type": "subscribe_success",
                "data": {
                    "element_id": group_id,
                    "subscription_type": "group_invite",
                },
            },
        )

        invite_id = await self.group_service.create_invite(
            user_id=user_id,
            group_id=group_id,
            description="foobar invite",
            single_use=False,
            valid_until=datetime.now() + timedelta(hours=4),
            join_as_editor=True,
        )

        await self.expect_ws_message(
            ws,
            {
                "type": "notification",
                "data": {
                    "element_id": group_id,
                    "invite_id": invite_id,
                    "subscription_type": "group_invite",
                },
            },
        )

        await ws.send_json({
            "type": "unsubscribe",
            "token": token,
            "data": {
                "subscription_type": "transaction",
                "element_id": group_id
            },
        })

        await self.expect_ws_message(
            ws,
            {
                "type": "unsubscribe_success",
                "data": {
                    "element_id": group_id,
                    "subscription_type": "transaction",
                },
            },
        )

        await ws.send_json({
            "type": "unsubscribe",
            "token": token,
            "data": {
                "subscription_type": "account",
                "element_id": group_id
            },
        })

        await self.expect_ws_message(
            ws,
            {
                "type": "unsubscribe_success",
                "data": {
                    "element_id": group_id,
                    "subscription_type": "account",
                },
            },
        )

        await ws.send_json({
            "type": "unsubscribe",
            "token": token,
            "data": {
                "subscription_type": "group",
                "element_id": user_id
            },
        })

        await self.expect_ws_message(
            ws,
            {
                "type": "unsubscribe_success",
                "data": {
                    "element_id": user_id,
                    "subscription_type": "group",
                },
            },
        )
Esempio n. 5
0
    async def test_delete_group(self):
        user2_id, user2_password = await self._create_test_user(
            "user2", "*****@*****.**")
        _, session_id, _ = await self.user_service.login_user(
            "user2", password=user2_password, session_name="foobar")
        user2_token = token_for_user(user2_id, session_id, self.secret_key)
        group_id = await self.group_service.create_group(
            user_id=self.test_user_id,
            name="foobar",
            description="foobar",
            currency_symbol="€",
            terms="foo",
        )
        async with self.db_pool.acquire() as conn:
            await conn.execute(
                "insert into group_membership (user_id, group_id, is_owner, can_write) "
                "values ($1, $2, true, true)",
                user2_id,
                group_id,
            )

        account1_id = await self.account_service.create_account(
            user_id=self.test_user_id,
            group_id=group_id,
            type="personal",
            name="account1",
            description="",
        )
        account2_id = await self.account_service.create_account(
            user_id=self.test_user_id,
            group_id=group_id,
            type="personal",
            name="account2",
            description="",
        )

        transaction_id = await self.transaction_service.create_transaction(
            user_id=self.test_user_id,
            group_id=group_id,
            type="purchase",
            description="asdf",
            billed_at=datetime.now(tz=timezone.utc),
            currency_symbol="€",
            currency_conversion_rate=1.0,
            value=20.0,
            debitor_shares={account1_id: 1.0},
            creditor_shares={account2_id: 1.0},
        )

        resp = await self._delete(f"/api/v1/groups/{group_id}")
        self.assertEqual(403, resp.status)

        resp = await self._post(f"/api/v1/groups/{group_id}/leave")
        self.assertEqual(204, resp.status)

        await self._fetch_group(group_id, expected_status=404)

        resp = await self.client.delete(
            f"/api/v1/groups/{group_id}",
            headers={"Authorization": f"Bearer {user2_token}"},
        )
        self.assertEqual(204, resp.status)

        async with self.db_pool.acquire() as conn:
            gid = await conn.fetchval("select id from grp where grp.id = $1",
                                      group_id)
            self.assertIsNone(gid)
Esempio n. 6
0
    async def test_invites(self):
        group_id = await self.group_service.create_group(
            user_id=self.test_user_id,
            name="group1",
            description="description",
            currency_symbol="€",
            terms="terms",
        )
        resp = await self._post(
            f"/api/v1/groups/{group_id}/invites",
            json={
                "description": "description",
                "single_use": False,
                "join_as_editor": False,
                "valid_until":
                (datetime.now() + timedelta(hours=1)).isoformat(),
            },
        )
        self.assertEqual(204, resp.status)

        resp = await self._get(f"/api/v1/groups/{group_id}/invites")
        self.assertEqual(200, resp.status)
        invites = await resp.json()
        self.assertEqual(1, len(invites))

        # we hardcode assume the invite id is 0 to check if the id counting works as expected
        resp = await self._delete(
            f"/api/v1/groups/{group_id}/invites/{invites[0]['id']}")
        self.assertEqual(204, resp.status)

        resp = await self._get(f"/api/v1/groups/{group_id}/invites")
        self.assertEqual(200, resp.status)
        invites = await resp.json()
        self.assertEqual(0, len(invites))

        # now check that we can actually preview the group as a different user
        resp = await self._post(
            f"/api/v1/groups/{group_id}/invites",
            json={
                "description": "description",
                "single_use": True,
                "join_as_editor": True,
                "valid_until":
                (datetime.now() + timedelta(hours=1)).isoformat(),
            },
        )
        self.assertEqual(204, resp.status)

        resp = await self._get(f"/api/v1/groups/{group_id}/invites")
        self.assertEqual(200, resp.status)
        invites = await resp.json()
        self.assertEqual(1, len(invites))
        invite_token = invites[0]["token"]
        self.assertIsNotNone(invite_token)

        user2_id, password = await self._create_test_user(
            "user", "*****@*****.**")
        _, session_id, _ = await self.user_service.login_user(
            "user", password=password, session_name="session1")
        jwt_token = token_for_user(user2_id,
                                   session_id=session_id,
                                   secret_key=self.secret_key)
        resp = await self.client.post(
            f"/api/v1/groups/preview",
            json={"invite_token": invite_token},
            headers={"Authorization": f"Bearer {jwt_token}"},
        )
        self.assertEqual(200, resp.status)
        prev_group_data = await resp.json()
        self.assertEqual("group1", prev_group_data["name"])
        self.assertEqual(group_id, prev_group_data["id"])

        resp = await self.client.post(
            f"/api/v1/groups/join",
            json={"invite_token": invite_token},
            headers={"Authorization": f"Bearer {jwt_token}"},
        )
        self.assertEqual(204, resp.status)

        resp = await self.client.get(
            f"/api/v1/groups",
            headers={"Authorization": f"Bearer {jwt_token}"},
        )
        self.assertEqual(200, resp.status)
        groups = await resp.json()
        self.assertEqual(1, len(groups))

        resp = await self._get(f"/api/v1/groups/{group_id}/invites")
        self.assertEqual(200, resp.status)
        invites = await resp.json()
        self.assertEqual(0, len(invites))

        resp = await self._get(f"/api/v1/groups/{group_id}/logs")
        self.assertEqual(200, resp.status)
        logs = await resp.json()
        self.assertEqual(6, len(logs))
        self.assertEqual(
            {
                "group-created", "member-joined", "invite-created",
                "invite-deleted"
            },
            set([log["type"] for log in logs]),
        )