Reputation: 1
I am having issue with my Streamlit app and not sure what am I missing. My app requires login at the startup and during the login process, it checks to see if the MFA has been activated for the account or not. In case the MFA is not activated, it will show the user a QR code to scan on Authenticator app to add the account then have the user enter the code from Authenticator app to activate the MFA for the account.
The app works up to the point of showing the QR code and accepting the code from the Authenticator app but skips executing the code from the if condition onwards on line 24.
Can anyone help me understand what am I missing here? I have validated the values of the EnableMFA variable and it is correct so If condition should be executing but its not.
import streamlit as st
import dblib as db
from sqlalchemy import text, case, update
import otp, qr
def activate_mfa(login):
if 'data' not in st.session_state:
st.session_state.sec_key = otp.generate_secret()
st.session_state.data = f'otpauth://totp/{login}?secret={st.session_state.sec_key}&issuer=timetracker'
st.write(f'MFA activation is required. Please scan the QR code with Authenticator app or you can manually add account with {st.session_state.sec_key} key')
col1,col2,col3 = st.columns([.25,.5,.25])
with col2:
img = qr.create_qr_code(data=st.session_state.data)
st.image(img)
with st.form('mfa',enter_to_submit=False):
c1,c2 = st.columns([.6,.4],vertical_alignment="bottom")
with c1:
EnableMFA = st.text_input("Enter OTP code from your app",key='k_enablemfacode')
with c2:
submit = st.form_submit_button('Activate MFA')
if submit:
st.info('OTP Submitted')
if len(EnableMFA) >= 0:
st.write(f'Key-> {st.session_state.sec_key} Data -> {st.session_state.data} OTP -> {EnableMFA}')
st.write('Validating otp...')
otp_valid = otp.validate_otp(EnableMFA,st.session_state.sec_key)
st.write(otp_valid)
if otp_valid:
st.session_state.MFAStatus = 'Active'
session = db.db_connect()
secure_mfakey = db.ed(st.session_state.sec_key,'encode')
mfa_activate = update(db.Users).where(db.Users.Login == login).values({db.Users.MFAStatus : secure_mfakey})
try:
session.execute(mfa_activate)
session.commit()
st.success('MFA activated successfully')
except Exception as e:
st.error(f'Error while activating MFA. {str(e)}')
session.rollback()
session.close()
else:
st.error('Invalid MFA code. Please try again')
After entering the MFA code, it goes back to the login screen and wouldn’t let me click the login butoon anymore. Only refreshing the screen from the browser will allow to interact with the app again.
View the screen recording if you like to see the behavior.
Upvotes: 0
Views: 35
Reputation: 1
This is solved finally. The issue was with how Streamlit handles the forms and their submission. Anytime a form is submitted, Streamlit will rerun the app or the code fragment which will reset the value for the variables in that fragment or the global variable if the app is rerun.
To solve this, I removed all the forms from the login module and combined the functions into single function so when the app is rerun, the value of the variable is not reset.
Upvotes: 0