Spaces:
Running
Running
mike boone commited on
Commit Β·
090128c
1
Parent(s): ece9b51
fix: force password change before app access
Browse files- chat_interface.py +98 -1
chat_interface.py
CHANGED
|
@@ -4868,8 +4868,34 @@ def create_chat_interface():
|
|
| 4868 |
population_code_state = gr.State("")
|
| 4869 |
live_progress_state = gr.State("")
|
| 4870 |
demo_pack_state = gr.State("")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4871 |
|
| 4872 |
-
with gr.Tabs():
|
| 4873 |
with gr.Tab("π± App"):
|
| 4874 |
chat_components = create_chat_tab(
|
| 4875 |
chat_controller_state, default_settings, current_stage, current_model,
|
|
@@ -5442,6 +5468,56 @@ def create_chat_interface():
|
|
| 5442 |
inputs=[],
|
| 5443 |
outputs=admin_outputs
|
| 5444 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5445 |
|
| 5446 |
# Create update function for tabs
|
| 5447 |
_spotter_waiting = "Story will be generated after liveboard creation."
|
|
@@ -5885,6 +5961,8 @@ def create_chat_tab(chat_controller_state, settings, current_stage, current_mode
|
|
| 5885 |
controller.settings['thoughtspot_url'] = _url
|
| 5886 |
if _key_value:
|
| 5887 |
controller.settings['thoughtspot_trusted_auth_key'] = _key_value
|
|
|
|
|
|
|
| 5888 |
# Always use the current UI values β take priority over DB-loaded defaults
|
| 5889 |
if liveboard_name_ui is not None:
|
| 5890 |
controller.settings['liveboard_name'] = liveboard_name_ui
|
|
@@ -5957,6 +6035,8 @@ def create_chat_tab(chat_controller_state, settings, current_stage, current_mode
|
|
| 5957 |
controller.settings['thoughtspot_url'] = _url
|
| 5958 |
if _key_value:
|
| 5959 |
controller.settings['thoughtspot_trusted_auth_key'] = _key_value
|
|
|
|
|
|
|
| 5960 |
if lb_name is not None:
|
| 5961 |
controller.settings['liveboard_name'] = lb_name
|
| 5962 |
if model:
|
|
@@ -5988,6 +6068,23 @@ def create_chat_tab(chat_controller_state, settings, current_stage, current_mode
|
|
| 5988 |
|
| 5989 |
is_custom = (vertical == "* CUSTOM *")
|
| 5990 |
hide_welcome = gr.update(visible=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5991 |
|
| 5992 |
if is_custom:
|
| 5993 |
# Custom: context field drives the use case
|
|
|
|
| 4868 |
population_code_state = gr.State("")
|
| 4869 |
live_progress_state = gr.State("")
|
| 4870 |
demo_pack_state = gr.State("")
|
| 4871 |
+
|
| 4872 |
+
with gr.Group(visible=False) as password_gate:
|
| 4873 |
+
gr.Markdown("""
|
| 4874 |
+
## Change Password Required
|
| 4875 |
+
|
| 4876 |
+
You are signed in with a temporary password. Set a new password before using DemoPrep.
|
| 4877 |
+
""")
|
| 4878 |
+
with gr.Row():
|
| 4879 |
+
with gr.Column(scale=1):
|
| 4880 |
+
gate_current_password = gr.Textbox(
|
| 4881 |
+
label="Temporary Password",
|
| 4882 |
+
type="password",
|
| 4883 |
+
placeholder="Enter the password you just used to sign in",
|
| 4884 |
+
)
|
| 4885 |
+
gate_new_password = gr.Textbox(
|
| 4886 |
+
label="New Password",
|
| 4887 |
+
type="password",
|
| 4888 |
+
placeholder="At least 8 characters",
|
| 4889 |
+
)
|
| 4890 |
+
gate_confirm_password = gr.Textbox(
|
| 4891 |
+
label="Confirm New Password",
|
| 4892 |
+
type="password",
|
| 4893 |
+
placeholder="Repeat new password",
|
| 4894 |
+
)
|
| 4895 |
+
gate_change_password_btn = gr.Button("Change Password", variant="primary")
|
| 4896 |
+
gate_password_status = gr.Markdown("")
|
| 4897 |
|
| 4898 |
+
with gr.Tabs(visible=False) as main_tabs:
|
| 4899 |
with gr.Tab("π± App"):
|
| 4900 |
chat_components = create_chat_tab(
|
| 4901 |
chat_controller_state, default_settings, current_stage, current_model,
|
|
|
|
| 5468 |
inputs=[],
|
| 5469 |
outputs=admin_outputs
|
| 5470 |
)
|
| 5471 |
+
|
| 5472 |
+
def check_password_gate(request: gr.Request = None):
|
| 5473 |
+
"""Show only the forced password-change panel for temp-password users."""
|
| 5474 |
+
try:
|
| 5475 |
+
user_email = require_authenticated_email(request)
|
| 5476 |
+
from supabase_client import UserManager
|
| 5477 |
+
um = UserManager()
|
| 5478 |
+
must_change = um.enabled and um.must_change_password(user_email)
|
| 5479 |
+
return gr.update(visible=must_change), gr.update(visible=not must_change)
|
| 5480 |
+
except Exception as e:
|
| 5481 |
+
print(f"[LOAD] password gate check skipped: {e}")
|
| 5482 |
+
return gr.update(visible=False), gr.update(visible=True)
|
| 5483 |
+
|
| 5484 |
+
def complete_required_password_change(current, new_pw, confirm, request: gr.Request = None):
|
| 5485 |
+
if not current or not new_pw or not confirm:
|
| 5486 |
+
return "β All fields are required.", gr.update(), gr.update()
|
| 5487 |
+
if new_pw != confirm:
|
| 5488 |
+
return "β New passwords don't match.", gr.update(), gr.update()
|
| 5489 |
+
if len(new_pw) < 8:
|
| 5490 |
+
return "β New password must be at least 8 characters.", gr.update(), gr.update()
|
| 5491 |
+
try:
|
| 5492 |
+
user_email = require_authenticated_email(request)
|
| 5493 |
+
from supabase_client import UserManager
|
| 5494 |
+
um = UserManager()
|
| 5495 |
+
if not um.enabled:
|
| 5496 |
+
return "β οΈ Supabase not configured β password change unavailable.", gr.update(), gr.update()
|
| 5497 |
+
if not um.authenticate(user_email, current):
|
| 5498 |
+
return "β Temporary password is incorrect.", gr.update(), gr.update()
|
| 5499 |
+
if not um.reset_password(user_email, new_pw, must_change_password=False):
|
| 5500 |
+
return "β Password change failed. Please try again or ask an admin to reset it.", gr.update(), gr.update()
|
| 5501 |
+
um.clear_must_change_password(user_email)
|
| 5502 |
+
return (
|
| 5503 |
+
"β
Password changed. DemoPrep is ready.",
|
| 5504 |
+
gr.update(visible=False),
|
| 5505 |
+
gr.update(visible=True),
|
| 5506 |
+
)
|
| 5507 |
+
except Exception as e:
|
| 5508 |
+
return f"β Error: {e}", gr.update(), gr.update()
|
| 5509 |
+
|
| 5510 |
+
interface.load(
|
| 5511 |
+
fn=check_password_gate,
|
| 5512 |
+
inputs=[],
|
| 5513 |
+
outputs=[password_gate, main_tabs],
|
| 5514 |
+
)
|
| 5515 |
+
|
| 5516 |
+
gate_change_password_btn.click(
|
| 5517 |
+
fn=complete_required_password_change,
|
| 5518 |
+
inputs=[gate_current_password, gate_new_password, gate_confirm_password],
|
| 5519 |
+
outputs=[gate_password_status, password_gate, main_tabs],
|
| 5520 |
+
)
|
| 5521 |
|
| 5522 |
# Create update function for tabs
|
| 5523 |
_spotter_waiting = "Story will be generated after liveboard creation."
|
|
|
|
| 5961 |
controller.settings['thoughtspot_url'] = _url
|
| 5962 |
if _key_value:
|
| 5963 |
controller.settings['thoughtspot_trusted_auth_key'] = _key_value
|
| 5964 |
+
elif username:
|
| 5965 |
+
controller.user_email = username
|
| 5966 |
# Always use the current UI values β take priority over DB-loaded defaults
|
| 5967 |
if liveboard_name_ui is not None:
|
| 5968 |
controller.settings['liveboard_name'] = liveboard_name_ui
|
|
|
|
| 6035 |
controller.settings['thoughtspot_url'] = _url
|
| 6036 |
if _key_value:
|
| 6037 |
controller.settings['thoughtspot_trusted_auth_key'] = _key_value
|
| 6038 |
+
elif username:
|
| 6039 |
+
controller.user_email = username
|
| 6040 |
if lb_name is not None:
|
| 6041 |
controller.settings['liveboard_name'] = lb_name
|
| 6042 |
if model:
|
|
|
|
| 6068 |
|
| 6069 |
is_custom = (vertical == "* CUSTOM *")
|
| 6070 |
hide_welcome = gr.update(visible=False)
|
| 6071 |
+
password_block = controller._temporary_password_block_message()
|
| 6072 |
+
if password_block:
|
| 6073 |
+
history = history or []
|
| 6074 |
+
history.append(("GO", password_block))
|
| 6075 |
+
controller.phase_log = ["Password change required before starting pipeline."]
|
| 6076 |
+
yield (
|
| 6077 |
+
controller,
|
| 6078 |
+
gr.update(value=history, visible=True),
|
| 6079 |
+
stage,
|
| 6080 |
+
model,
|
| 6081 |
+
company,
|
| 6082 |
+
usecase,
|
| 6083 |
+
get_progress_html(stage),
|
| 6084 |
+
hide_welcome,
|
| 6085 |
+
gr.update(open=False),
|
| 6086 |
+
)
|
| 6087 |
+
return
|
| 6088 |
|
| 6089 |
if is_custom:
|
| 6090 |
# Custom: context field drives the use case
|