Skip to content

Commit 8884e59

Browse files
committed
fixes #80
1 parent c4ca963 commit 8884e59

File tree

4 files changed

+136
-3
lines changed

4 files changed

+136
-3
lines changed

ngwidgets/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.22.2"
1+
__version__ = "0.22.3"

ngwidgets/sso_users_solution.py

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
"""
2+
Created on 2025-02-15
3+
4+
@author: wf
5+
"""
6+
7+
from fastapi.responses import RedirectResponse
8+
from ngwidgets.login import Login
9+
from ngwidgets.webserver import WebSolution, NiceGuiWebserver
10+
from nicegui import Client, ui
11+
from wikibot3rd.sso import User
12+
from wikibot3rd.sso_users import Sso_Users
13+
14+
class SsoSolution(WebSolution):
15+
"""
16+
Encapsulates SSO authentication setup and user handling
17+
"""
18+
def __init__(self, webserver: NiceGuiWebserver, client: Client = None, credentials_path=None):
19+
"""
20+
Initialize SSO authentication
21+
22+
Args:
23+
webserver: The webserver instance to set up SSO for
24+
client: The client instance (can be None for non-client specific solutions)
25+
credentials_path: Optional path to the SSO credentials file
26+
"""
27+
super().__init__(webserver, client) # Call parent constructor with both required parameters
28+
self.users = Sso_Users(webserver.config.short_name, credentials_path=credentials_path)
29+
30+
self.login = Login(webserver, self.users)
31+
32+
def get_user(self) -> User:
33+
"""
34+
Get the current authenticated user
35+
36+
Returns:
37+
User: The current user object or None if not authenticated
38+
"""
39+
user = None
40+
username = self.login.get_username()
41+
if username and self.users.is_available:
42+
user = self.users.sso.get_user(username)
43+
return user
44+
45+
def get_user_display_name(self) -> str:
46+
"""
47+
Get the display name for the current user with admin indicator
48+
49+
Returns:
50+
str: Username with optional admin indicator
51+
"""
52+
username = self.login.get_username()
53+
if username is None:
54+
username = "?"
55+
user = self.get_user()
56+
admin_flag = "🔑" if user and user.is_admin else ""
57+
user_display = f"{username}{admin_flag}"
58+
return user_display
59+
60+
async def logout(self):
61+
"""Handle user logout"""
62+
await self.login.logout()
63+
64+
def as_html(self) -> str:
65+
"""
66+
Get the user details as HTML markup
67+
68+
Returns:
69+
str: HTML markup for the user details or error message
70+
"""
71+
user = self.get_user()
72+
html_markup = "<h1>User Details</h1>"
73+
if not user:
74+
html_markup += "<p>No user logged in</p>"
75+
else:
76+
html_markup += f"""
77+
<p><strong>ID:</strong> {user.id}</p>
78+
<p><strong>Name:</strong> {user.name}</p>
79+
<p><strong>Real Name:</strong> {user.real_name}</p>
80+
<p><strong>Email:</strong> {user.email}</p>
81+
<p><strong>Edit Count:</strong> {user.editcount}</p>
82+
"""
83+
return html_markup
84+
85+
async def show_login(self):
86+
"""Show the login page"""
87+
await self.login.login(self)
88+
89+
async def show_user_details(self):
90+
"""Show the user details page"""
91+
def show():
92+
self.logout_button = ui.button(
93+
"logout", icon="logout",
94+
on_click=self.logout
95+
)
96+
ui.html(self.as_html())
97+
await self.setup_content_div(show)
98+
99+
def configure_menu(self):
100+
"""Configure the user menu"""
101+
display_name = self.get_user_display_name()
102+
self.link_button(display_name, "/user", "person")
103+
# make sure the link exists
104+
self.register_pages()
105+
106+
def register_pages(self):
107+
"""Register the SSO-related pages"""
108+
@ui.page("/user")
109+
async def show_user(client: Client):
110+
if not self.login.authenticated():
111+
return RedirectResponse("/login")
112+
return await self.webserver.execute_action(
113+
client,
114+
solution_class=SsoSolution,
115+
wanted_action=SsoSolution.show_user_details
116+
)
117+
118+
@ui.page("/login")
119+
async def login(client: Client):
120+
return await self.webserver.execute_action(
121+
client,
122+
solution_class=SsoSolution,
123+
wanted_action=SsoSolution.show_login
124+
)

ngwidgets/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class Version:
1717
name = "ngwidgets"
1818
version = ngwidgets.__version__
1919
date = "2023-09-10"
20-
updated = "2025-02-24"
20+
updated = "2025-03-08"
2121
description = "NiceGUI widgets"
2222

2323
authors = "Wolfgang Fahl"

ngwidgets/widgets_demo.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from ngwidgets.webserver import WebserverConfig
3232
from ngwidgets.widgets import HideShow, Lang, Link
3333
from ngwidgets.wikipedia import WikipediaSearch
34+
from ngwidgets.sso_users_solution import SsoSolution
3435

3536

3637
@dataclass
@@ -837,6 +838,14 @@ async def show():
837838

838839
await self.setup_content_div(show)
839840

841+
def configure_menu(self):
842+
"""
843+
configure my menu
844+
"""
845+
InputWebSolution.configure_menu(self)
846+
self.sso_solution = SsoSolution(webserver=self.webserver)
847+
self.sso_solution.configure_menu()
848+
840849
async def home(self):
841850
"""
842851
provide the main content page
@@ -881,7 +890,7 @@ class NiceGuiWidgetsDemoWebserver(InputWebserver):
881890

882891
@classmethod
883892
def get_config(cls) -> WebserverConfig:
884-
copy_right = "(c)2023-2024 Wolfgang Fahl"
893+
copy_right = "(c)2023-2025 Wolfgang Fahl"
885894
config = WebserverConfig(
886895
short_name="ngdemo",
887896
timeout=6.0,

0 commit comments

Comments
 (0)