-
Notifications
You must be signed in to change notification settings - Fork 4k
Description
Checklist
- I have searched the existing issues for similar issues.
- I added a very descriptive title to this issue.
- I have provided sufficient information below to help reproduce this issue.
Summary
The error log is being generated during a logout. It does not brake the the logging out sequence, the app does not fail, but the error is logged (triggering my app alerts).
I believe this is because the check for the provider is happening after the session has been cleared and a new one created.
There maybe a specific need for the error handler to check the provider in the session, I am not sure, but I wonder if it should be checking for the provider in the secrest.toml config instead.
Here the function I am referring to: https://github.com/streamlit/streamlit/blob/develop/lib/streamlit/web/server/oauth_authlib_routes.py#L164
Reproducible Code Example
import logging
import os
import time
import streamlit as st
import yaml
from auth import Auth
# For a local run using .env file
if os.environ.get("ENV_SHORT", "LOCAL") == "LOCAL":
from dotenv import load_dotenv
load_dotenv()
logging.basicConfig(level='INFO')
logger = logging.getLogger('app.py')
def sso_login():
"""Re-direct the user to Microsoft SSO."""
if st.session_state["env_short"].lower() == "uat":
st.title('Streamlit Forms - Testing')
st.warning("This is a **Testing** environment! \nUse this link for live environment: https://...")
else:
st.title('Streamlit Forms')
if st.button("Log in with Microsoft"):
st.login("microsoft")
st.stop()
def logout():
"""Clear the cookies and session state vars."""
st.session_state.groups = []
st.logout()
st.info("User logged out.")
def forms_pages(groups):
logoutPage = st.Page(
logout,
title="Log out",
icon=":material/logout:",
)
noAccess = st.Page(
no_access,
title="Home",
icon=":material/home:",
)
try:
with open('forms/config.yml') as file:
forms_config = yaml.safe_load(file)
forms_config = forms_config['forms']
formsPages = []
# Check if the the user is part of the azure groups included in the Forms config.yml file.
group_set = set(groups)
for form, values in forms_config.items():
groups_ids = [group['id'] for group in values['groups']]
groups_match = group_set.intersection(set(groups_ids))
# Create the Form page for each match between the config.yml and azure groups the user is member of.
if len(groups_match) != 0:
formsPages.append(
st.Page(
f"forms/{form}.py",
title=values['title'],
)
)
# If there is no match, point the user to the No Access and Log Out pages to request the access
if len(formsPages) > 0:
pg = st.navigation(
{"Home":formsPages} | {"Account":[logoutPage]}
)
pg.run()
else:
pg = st.navigation(
{"Account":[noAccess, logoutPage]}
)
pg.run()
except Exception as error:
logger.error(f"Something went wrong during the creation of the Forms pages: {error}")
# Set up variable for session expiry in 8 hours.
current_time = int(time.time())
hours_in_session = 8 * 60 * 60
# Set up environement:
if "env_short" not in st.session_state:
st.session_state["env_short"] = os.environ["ENV_SHORT"]
if "groups" not in st.session_state:
st.session_state["groups"] = []
# Access checks
try:
if "error" in st.user:
st.error("Something went wrong, please **Try Again** or **Raise a Ticket** if the error persists.")
logger.info(f"Something went wrong during logging attempt via SSO: {st.user.to_dict()}")
log_again = st.button("Try Again",type="primary")
if log_again:
st.logout()
raise_a_ticket = st.button("Raise a Ticket",type="secondary")
if raise_a_ticket:
logger.error(f"Something went wrong during logging via SSO: {st.user.to_dict()}")
elif not st.user["is_logged_in"]:
if st.session_state["env_short"].lower() == "uat":
page_title = 'Streamlit Forms - Testing'
else:
page_title = 'Streamlit Forms'
pg = st.navigation(
{"Home":[
st.Page(
sso_login,
title=page_title,
icon=":material/login:"
)
]
}
)
pg.run()
# Delete `st.user` cookies if stayed logged over two days.
elif current_time > (st.user.exp + hours_in_session):
logger.info(f"Current time is greater than the exp date. Unicode time: {st.user.exp}. Logging out.")
st.logout()
# Render corresponding Forms pages if groups already stored in the state.
elif len(st.session_state["groups"]) > 0:
logger.info(f"Groups stored in session state. Number of groups:{len(st.session_state.groups)}")
forms_pages(st.session_state["groups"])
# Get list of groups.
elif len(st.session_state["groups"]) == 0:
logger.info("Large group list, calling the API to get all the groups...")
client_id = st.secrets["auth"]["microsoft"]["client_id"]
client_secret = st.secrets["auth"]["microsoft"]["client_secret"]
tenant = st.secrets["auth"]["microsoft"]["tenant"]
auth = Auth(client_id=client_id,client_secret=client_secret,tenant=tenant)
st.session_state["groups"] = auth.get_groups(st.user["oid"])
logger.info(f"Fetched the large group list. API response object type: {type(st.session_state['groups'])}.")
forms_pages(st.session_state["groups"])
except Exception as error:
st.error(
"Something went wrong, please **Try Again** "
"or **Raise a Ticket** if the error persists."
)
log_again = st.button("Try Again",type="primary")
if log_again:
st.logout()
raise_a_ticket = st.button("Raise a Ticket",type="secondary")
if raise_a_ticket:
logger.error(f"Something went wrong during the Access Check: {error}")Steps To Reproduce
- Log in
- Refresh browser
- Logout
Expected Behavior
Since the provider is available in the secrets.toml there should not be an error log when a session is reset.
Current Behavior
Error Message:
Error, missing provider for oauth callback
Is this a regression?
- Yes, this used to work in a previous version.
Debug info
- Streamlit version: 1.50.0
- Python version: 3.11
- Operating System: debian:13
- Browser: Edge (might be others too)
Additional Information
This issue didn't occur prior version 1.47.0