Fix security issue - data sharing above users

This commit is contained in:
2023-12-12 18:14:36 +03:00
parent 045f78156a
commit 31e92a2f00
6 changed files with 49 additions and 30 deletions

View File

@@ -21,7 +21,6 @@ class SoulDiaryApp:
): ):
self._backend = backend self._backend = backend
self._backend_data = backend_data self._backend_data = backend_data
self._backend_client = None
def get_routes(self, page: flet.Page) -> dict[str, BaseView]: def get_routes(self, page: flet.Page) -> dict[str, BaseView]:
local_storage = LocalStorage(client_storage=page.client_storage) local_storage = LocalStorage(client_storage=page.client_storage)
@@ -35,7 +34,7 @@ class SoulDiaryApp:
backend_data=self._backend_data, backend_data=self._backend_data,
), ),
SENSE_LIST: sense_list_view, SENSE_LIST: sense_list_view,
SENSE_ADD: SenseAddView(), SENSE_ADD: SenseAddView(local_storage=local_storage),
} }
async def run(self, page: flet.Page): async def run(self, page: flet.Page):

View File

@@ -1,36 +1,21 @@
import flet import flet
from flet_route import Basket, Params from flet_route import Basket, Params
from soul_diary.ui.app.backend.local import LocalBackend
from soul_diary.ui.app.local_storage import LocalStorage from soul_diary.ui.app.local_storage import LocalStorage
from soul_diary.ui.app.models import BackendType from soul_diary.ui.app.models import BackendType
from soul_diary.ui.app.routes import AUTH, SENSE_LIST from soul_diary.ui.app.routes import AUTH, SENSE_LIST
async def middleware(page: flet.Page, params: Params, basket: Basket): async def middleware(page: flet.Page, params: Params, basket: Basket):
if getattr(page.app, "backend_client", None) is not None:
if page.route == AUTH:
await page.go_async(SENSE_LIST)
return
local_storage = LocalStorage(client_storage=page.client_storage) local_storage = LocalStorage(client_storage=page.client_storage)
auth_data = await local_storage.get_auth_data() auth_data = await local_storage.get_auth_data()
if auth_data is None: if auth_data is None:
await page.go_async(AUTH) await page.go_async(AUTH)
return return
if auth_data.backend == BackendType.LOCAL: if auth_data.backend not in BackendType:
backend_client_class = LocalBackend
else:
await page.go_async(AUTH) await page.go_async(AUTH)
return return
page.app.backend_client = backend_client_class(
local_storage=local_storage,
username=auth_data.username,
encryption_key=auth_data.encryption_key,
token=auth_data.token,
**auth_data.backend_data,
)
if page.route == AUTH: if page.route == AUTH:
await page.go_async(SENSE_LIST) await page.go_async(SENSE_LIST)

View File

@@ -27,14 +27,13 @@ class AuthView(BaseView):
self.center_container: flet.Container self.center_container: flet.Container
self.bottom_container: flet.Container self.bottom_container: flet.Container
self.local_storage = local_storage
self.initial_backend = self.backend = backend self.initial_backend = self.backend = backend
self.initial_backend_data = self.backend_data = backend_data or {} self.initial_backend_data = self.backend_data = backend_data or {}
self.backend_registration_enabled: bool = True self.backend_registration_enabled: bool = True
self.username: str | None = None self.username: str | None = None
self.password: str | None = None self.password: str | None = None
super().__init__(middlewares=middlewares) super().__init__(local_storage=local_storage, middlewares=middlewares)
async def clear(self): async def clear(self):
self.top_container.content = None self.top_container.content = None
@@ -282,7 +281,6 @@ class AuthView(BaseView):
await event.page.update_async() await event.page.update_async()
return return
event.page.app.backend_client = backend_client
await event.page.go_async(SENSE_LIST) await event.page.go_async(SENSE_LIST)
async def callback_signup( async def callback_signup(
@@ -312,7 +310,6 @@ class AuthView(BaseView):
await event.page.update_async() await event.page.update_async()
return return
event.page.app.backend_client = backend_client
await event.page.go_async(SENSE_LIST) await event.page.go_async(SENSE_LIST)
async def callback_go_backend(self, event: flet.ControlEvent): async def callback_go_backend(self, event: flet.ControlEvent):

View File

@@ -5,7 +5,12 @@ from typing import Any, Callable, Sequence
import flet import flet
from flet_route import Basket, Params from flet_route import Basket, Params
from soul_diary.ui.app.backend.base import BaseBackend
from soul_diary.ui.app.backend.exceptions import NonAuthenticatedException
from soul_diary.ui.app.backend.local import LocalBackend
from soul_diary.ui.app.local_storage import LocalStorage
from soul_diary.ui.app.middlewares.base import BaseMiddleware from soul_diary.ui.app.middlewares.base import BaseMiddleware
from soul_diary.ui.app.models import BackendType
def view(initial: bool = False, disabled: bool = False): def view(initial: bool = False, disabled: bool = False):
@@ -65,7 +70,12 @@ class BaseView(metaclass=MetaView):
is_abstract = True is_abstract = True
_initial_view: Callable | None _initial_view: Callable | None
def __init__(self, middlewares: Sequence[BaseMiddleware | Callable] = ()): def __init__(
self,
local_storage: LocalStorage,
middlewares: Sequence[BaseMiddleware | Callable] = (),
):
self.local_storage = local_storage
self.middlewares = middlewares self.middlewares = middlewares
self.container: flet.Container self.container: flet.Container
@@ -115,3 +125,21 @@ class BaseView(metaclass=MetaView):
async def run_initial_view(self, page: flet.Page): async def run_initial_view(self, page: flet.Page):
if self._initial_view is not None: if self._initial_view is not None:
await self._initial_view(page=page) await self._initial_view(page=page)
async def get_backend_client(self, page: flet.Page) -> BaseBackend:
auth_data = await self.local_storage.get_auth_data()
if auth_data is None:
raise NonAuthenticatedException()
if auth_data.backend == BackendType.LOCAL:
backend_client_class = LocalBackend
else:
raise
return backend_client_class(
local_storage=self.local_storage,
username=auth_data.username,
encryption_key=auth_data.encryption_key,
token=auth_data.token,
**auth_data.backend_data,
)

View File

@@ -3,6 +3,7 @@ from typing import Awaitable, Callable, Sequence
import flet import flet
from soul_diary.ui.app.local_storage import LocalStorage
from soul_diary.ui.app.middlewares.base import BaseMiddleware from soul_diary.ui.app.middlewares.base import BaseMiddleware
from soul_diary.ui.app.models import Emotion from soul_diary.ui.app.models import Emotion
from soul_diary.ui.app.routes import SENSE_ADD, SENSE_LIST from soul_diary.ui.app.routes import SENSE_ADD, SENSE_LIST
@@ -12,6 +13,7 @@ from .base import BaseView, view
class SenseAddView(BaseView): class SenseAddView(BaseView):
def __init__( def __init__(
self, self,
local_storage: LocalStorage,
middlewares: Sequence[BaseMiddleware | Callable[[flet.Page], Awaitable]] = (), middlewares: Sequence[BaseMiddleware | Callable[[flet.Page], Awaitable]] = (),
): ):
self.title: flet.Text self.title: flet.Text
@@ -23,7 +25,7 @@ class SenseAddView(BaseView):
self.body: str | None = None self.body: str | None = None
self.desires: str | None = None self.desires: str | None = None
super().__init__(middlewares=middlewares) super().__init__(local_storage=local_storage, middlewares=middlewares)
async def clear(self): async def clear(self):
self.title.value = "" self.title.value = ""
@@ -223,8 +225,9 @@ class SenseAddView(BaseView):
await event.page.update_async() await event.page.update_async()
return return
backend_client = await self.get_backend_client(page=event.page)
async with self.in_progress(page=event.page): async with self.in_progress(page=event.page):
await event.page.app.backend_client.create_sense( await backend_client.create_sense(
emotions=self.emotions, emotions=self.emotions,
feelings=self.feelings, feelings=self.feelings,
body=self.body, body=self.body,

View File

@@ -2,10 +2,11 @@ import asyncio
from typing import Awaitable, Callable, Sequence from typing import Awaitable, Callable, Sequence
import flet import flet
from soul_diary.ui.app.backend.exceptions import NonAuthenticatedException
from soul_diary.ui.app.local_storage import LocalStorage from soul_diary.ui.app.local_storage import LocalStorage
from soul_diary.ui.app.middlewares.base import BaseMiddleware from soul_diary.ui.app.middlewares.base import BaseMiddleware
from soul_diary.ui.app.models import Sense from soul_diary.ui.app.models import BackendType, Sense
from soul_diary.ui.app.routes import AUTH, SENSE_ADD, SENSE_LIST from soul_diary.ui.app.routes import AUTH, SENSE_ADD, SENSE_LIST
from .base import BaseView, view from .base import BaseView, view
@@ -20,7 +21,7 @@ class SenseListView(BaseView):
self.local_storage = local_storage self.local_storage = local_storage
super().__init__(middlewares=middlewares) super().__init__(local_storage=local_storage, middlewares=middlewares)
async def setup(self): async def setup(self):
self.cards = flet.Column(alignment=flet.alignment.center, width=400) self.cards = flet.Column(alignment=flet.alignment.center, width=400)
@@ -69,7 +70,14 @@ class SenseListView(BaseView):
loop.create_task(self.render_sense_list(page=page)) loop.create_task(self.render_sense_list(page=page))
async def render_sense_list(self, page: flet.Page): async def render_sense_list(self, page: flet.Page):
senses = await page.app.backend_client.get_sense_list() auth_data = await self.local_storage.get_auth_data()
if auth_data is None:
raise NonAuthenticatedException()
if auth_data.backend == BackendType.LOCAL:
pass
backend_client = await self.get_backend_client(page=page)
senses = await backend_client.get_sense_list()
self.cards.controls = [await self.render_card_from_sense(sense) for sense in senses] self.cards.controls = [await self.render_card_from_sense(sense) for sense in senses]
await page.update_async() await page.update_async()
@@ -91,5 +99,4 @@ class SenseListView(BaseView):
async def callback_logout(self, event: flet.ControlEvent): async def callback_logout(self, event: flet.ControlEvent):
await self.local_storage.remove_auth_data() await self.local_storage.remove_auth_data()
event.page.app.backend_client = None
await event.page.go_async(AUTH) await event.page.go_async(AUTH)