diff --git a/core/data/schema/user.py b/core/data/schema/user.py index 8686f08..db6b71e 100644 --- a/core/data/schema/user.py +++ b/core/data/schema/user.py @@ -124,3 +124,15 @@ class UserData(BaseData): async def get_user_by_username(self, username: str) -> Optional[Row]: result = await self.execute(aime_user.select(aime_user.c.username == username)) if result: return result.fetchone() + + async def change_permission(self, user_id: int, new_perms: int) -> Optional[bool]: + sql = aime_user.update(aime_user.c.id == user_id).values(permissions = new_perms) + + result = await self.execute(sql) + return result is not None + + async def change_email(self, user_id: int, new_email: int) -> Optional[bool]: + sql = aime_user.update(aime_user.c.id == user_id).values(email = new_email) + + result = await self.execute(sql) + return result is not None diff --git a/tui.py b/tui.py index b140964..58d062f 100644 --- a/tui.py +++ b/tui.py @@ -77,10 +77,10 @@ class State: return self.id if self.id else 0 def __init__(self): - self.selected_user: self.SelectedUser = self.SelectedUser() - self.selected_card: self.SelectedCard = self.SelectedCard() - self.selected_arcade: self.SelectedArcade = self.SelectedArcade() - self.selected_machine: self.SelectedMachine = self.SelectedMachine() + self.selected_user = self.SelectedUser() + self.selected_card = self.SelectedCard() + self.selected_arcade = self.SelectedArcade() + self.selected_machine = self.SelectedMachine() self.last_err: str = "" self.search_results: List[Row] = [] self.search_type: str = "" @@ -89,6 +89,7 @@ class State: self.selected_user = self.SelectedUser(id, username) def clear_user(self) -> None: + print(self.selected_user) self.selected_user = self.SelectedUser() def set_card(self, id: int, access_code: Optional[str]) -> None: @@ -528,6 +529,89 @@ class LookupUserView(Frame): self.find_widget('status').value = state.last_err raise NextScene("User Management") +class EditUserView(Frame): + def __init__(self, screen): + super(EditUserView, self).__init__( + screen, + screen.height * 2 // 3, + screen.width * 2 // 3, + hover_focus=True, + can_scroll=False, + title="Edit User", + on_load=self._redraw + ) + + layout = Layout([100], fill_frame=True) + self.add_layout(layout) + layout.add_widget(Text("Username:", "username")) + layout.add_widget(Text("Email:", "email")) + layout.add_widget(Text("Password:", "passwd")) + layout.add_widget(RadioButtons([ + ("User", "1"), + ("User Manager", "2"), + ("Arcde Manager", "4"), + ("Sysadmin", "8"), + ("Owner", "255"), + ], "Role:", "role")) + + layout3 = Layout([100]) + self.add_layout(layout3) + layout3.add_widget(Text("", f"status", readonly=True, disabled=True)) + + layout2 = Layout([1, 1, 1, 1]) + self.add_layout(layout2) + layout2.add_widget(Button("Save", self._ok), 0) + layout2.add_widget(Button("Cancel", self._cancel), 3) + + self.fix() + + def _redraw(self): + uinfo = loop.run_until_complete(data.user.get_user(state.selected_user.id)) + self.find_widget('username').value = uinfo['username'] + self.find_widget('email').value = uinfo['email'] + self.find_widget('role').value = str(uinfo['permissions']) + + def _ok(self): + self.save() + if not self.data.get("username"): + state.set_last_err("Username cannot be blank") + self.find_widget('status').value = state.last_err + self.screen.reset() + return + + state.clear_last_err() + self.find_widget('status').value = state.last_err + + pw = self.data.get("passwd") + hash = bcrypt.hashpw(pw.encode(), bcrypt.gensalt()) + + is_good = loop.run_until_complete(self._update_user_async(self.data.get("username"), hash.decode(), self.data.get("email"), self.data.get('role'))) + + self.find_widget('status').value = "User Updated" if is_good else "User update failed" + + raise NextScene("User Management") + + async def _update_user_async(self, username: Optional[str], password: Optional[str], email: Optional[str], role: Optional[str]) -> bool: + if username: namechange_ok = await data.user.change_username(state.selected_user.id, username) + else: namechange_ok = True + + if password: pw_ok = await data.user.change_password(state.selected_user.id, password) + else: pw_ok = True + + if role: role_ok = await data.user.change_permission(state.selected_user.id, role) + else: role_ok = True + + if email: email_ok = await data.user.change_email(state.selected_user.id, email) + else: email_ok = True + + state.set_user(state.selected_user.id, username if username and namechange_ok else state.selected_user.name) + return namechange_ok and pw_ok and role_ok and email_ok + + def _cancel(self): + state.clear_last_err() + self.find_widget('status').value = state.last_err + raise NextScene("User Management") + def demo(screen:Screen, scene: Scene): scenes = [ Scene([MainView(screen)], -1, name="Main"), @@ -536,6 +620,7 @@ def demo(screen:Screen, scene: Scene): Scene([LookupUserView(screen)], -1, name="Lookup User"), Scene([SearchResultsView(screen)], -1, name="Search Results"), Scene([ManageCard(screen)], -1, name="Card Management"), + Scene([EditUserView(screen)], -1, name="Edit User"), ] screen.play(scenes, stop_on_resize=False, start_scene=scene, allow_int=True)