Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| from datetime import datetime | |
| from supabase import create_client, Client | |
| from utilities_option_menu.option_menu import option_menu | |
| import utilities_database.user_database_utils as db_utils | |
| from utilities_cookies.encrypted_cookie_manager import EncryptedCookieManager | |
| DB_URL = st.secrets['SUPABASE_URL'] | |
| DB_KEY = st.secrets['SUPABASE_KEY'] | |
| Client = create_client(DB_URL, DB_KEY) | |
| user_login_table = Client.table('UserLogIn') | |
| user_save_text_table = Client.table('TaskData') | |
| st.set_page_config(page_title='GenLexTasksEnter', layout="wide", page_icon=':es:') | |
| login_call = 'Зарегистрироваться' | |
| class LogIn: | |
| """ | |
| Builds the UI for the Login/ Sign Up page. | |
| """ | |
| def __init__(self, | |
| auth_token: str, | |
| company_name: str, | |
| width, height, | |
| logout_button_name: str = 'Logout', | |
| hide_menu_bool: bool = False, | |
| hide_footer_bool: bool = False, | |
| lottie_url: str = "https://assets8.lottiefiles.com/packages/lf20_ktwnwv5m.json"): | |
| """ | |
| Arguments: | |
| ----------- | |
| 1. self | |
| 2. auth_token : The unique authorization token received from - https://www.courier.com/email-api/ | |
| 3. company_name : This is the name of the person/ organization which will send the password reset email. | |
| 4. width : Width of the animation on the login page. | |
| 5. height : Height of the animation on the login page. | |
| 6. logout_button_name : The logout button name. | |
| 7. hide_menu_bool : Pass True if the streamlit menu should be hidden. | |
| 8. hide_footer_bool : Pass True if the 'made with streamlit' footer should be hidden. | |
| 9. lottie_url : The lottie animation you would like to use on the login page. | |
| Explore animations at - https://lottiefiles.com/featured | |
| """ | |
| self.auth_token = auth_token | |
| self.company_name = company_name | |
| self.width = width | |
| self.height = height | |
| self.logout_button_name = logout_button_name | |
| self.hide_menu_bool = hide_menu_bool | |
| self.hide_footer_bool = hide_footer_bool | |
| self.lottie_url = lottie_url | |
| self.cookies = EncryptedCookieManager( | |
| prefix="streamlit_login_ui_yummy_cookies", | |
| password='9d68d6f2-4258-45c9-96eb-2d6bc74ddbb5-d8f49cab-edbb-404a-94d0-b25b1d4a564b') | |
| if not self.cookies.ready(): | |
| st.stop() | |
| def get_user_name(self): | |
| if not st.session_state['LOGOUT_BUTTON_HIT']: | |
| fetched_cookies = self.cookies | |
| if '__streamlit_login_signup_ui_username__' in fetched_cookies.keys(): | |
| user_name = fetched_cookies['__streamlit_login_signup_ui_username__'] | |
| return user_name | |
| def login_widget(self) -> None: | |
| """ | |
| Creates the login widget, checks and sets cookies, authenticates the users. | |
| """ | |
| # Checks if cookie exists. | |
| if not st.session_state['LOGGED_IN'] and not st.session_state['LOGOUT_BUTTON_HIT']: | |
| fetched_cookies = self.cookies | |
| if '__streamlit_login_signup_ui_username__' in fetched_cookies.keys(): | |
| if fetched_cookies['__streamlit_login_signup_ui_username__'] \ | |
| != '1c9a923f-fb21-4a91-b3f3-5f18e3f01182': | |
| st.session_state['LOGGED_IN'] = True | |
| if not st.session_state['LOGGED_IN']: | |
| st.session_state['LOGOUT_BUTTON_HIT'] = False | |
| del_login = st.empty() | |
| with del_login.form("Login Form"): | |
| user_name = st.text_input("Имя пользователя", placeholder='Ваше имя пользователя') | |
| password = st.text_input("Пароль", placeholder='Ваш пароль', type='password') | |
| login_submit_button = st.form_submit_button(label='Войти') | |
| if login_submit_button: | |
| authenticate_user_check = db_utils.check_usr_pass(user_log_in_database=user_login_table, | |
| user_name=user_name, | |
| password=password) | |
| if not authenticate_user_check: | |
| st.error("Неверное имя пользователя или пароль!") | |
| else: | |
| st.session_state['LOGGED_IN'] = True | |
| st.session_state['-USER_NAME-'] = user_name | |
| self.cookies['__streamlit_login_signup_ui_username__'] = user_name | |
| self.cookies.save() | |
| del_login.empty() | |
| st.rerun() | |
| def sign_up_widget() -> None: | |
| """ | |
| Creates the sign-up widget and stores the user info in a secure way in the _secret_auth_.json file. | |
| """ | |
| with st.form("Sign Up Form"): | |
| name_sign_up = st.text_input("Имя *", | |
| placeholder='Введите Ваше имя') | |
| valid_name_check = db_utils.check_valid_name(name_sign_up) | |
| email_sign_up = st.text_input("E-mail *", | |
| placeholder='Введите Ваш e-mail') | |
| valid_email_check = db_utils.check_valid_email(email_sign_up) | |
| unique_email_check = db_utils.check_unique_email(user_log_in_database=user_login_table, | |
| email_sign_up=email_sign_up) | |
| user_name_sign_up = st.text_input("Имя пользователя *", | |
| placeholder='Введите имя пользователя (латинские буквы и символы)') | |
| unique_user_name_check = db_utils.check_unique_usr(user_log_in_database=user_login_table, | |
| user_name_sign_up=user_name_sign_up) | |
| password_sign_up = st.text_input("Пароль *", | |
| placeholder='Введите пароль', | |
| type='password') | |
| professional_level = st.radio('Вы являетесь преподавателем испанского языка? *', | |
| options=['Да', 'Нет'], | |
| index=1, | |
| horizontal=True) | |
| st.markdown("\* Обязательное поле") | |
| sign_up_submit_button = st.form_submit_button(label=login_call) | |
| if sign_up_submit_button: | |
| if not valid_name_check: | |
| st.error("Пожалуйста, ведите Ваше имя!") | |
| elif not valid_email_check: | |
| st.error("Пожалуйста, введите действующий е-mail!") | |
| elif not unique_email_check: | |
| st.error("Пользователь с этим e-mail уже зарегистрирован!") | |
| elif not unique_user_name_check: | |
| st.error(f'Извините, пользователь с таким именем ({user_name_sign_up}) уже существует!') | |
| elif unique_user_name_check is None: | |
| st.error('Пожалуйста, введите имя пользователя!') | |
| if valid_name_check: | |
| if valid_email_check and unique_email_check and unique_user_name_check: | |
| db_utils.register_new_usr(user_log_in_database=user_login_table, | |
| name_sign_up=name_sign_up, | |
| email_sign_up=email_sign_up, | |
| user_name_sign_up=user_name_sign_up, | |
| password_sign_up=password_sign_up, | |
| professional_level=professional_level, | |
| created_at=str(datetime.now())[:-7]) | |
| st.success("Регистрация прошла успешно!") | |
| def forgot_password(self) -> None: | |
| """ | |
| Creates the forgot password widget and after user authentication (e-mail), triggers an e-mail to the user | |
| containing a random password. | |
| """ | |
| with st.form("Forgot Password Form"): | |
| email_forgot_passwd = st.text_input("Email", placeholder='Введите Ваш email') | |
| email_exists_check, user_name_forgot_passwd = db_utils.check_email_exists( | |
| user_log_in_database=user_login_table, | |
| email_forgot_passwd=email_forgot_passwd) | |
| forgot_passwd_submit_button = st.form_submit_button(label='Получить пароль') | |
| if forgot_passwd_submit_button: | |
| if not email_exists_check: | |
| st.error("Пользователя с таким e-mail не существует!") | |
| if email_exists_check: | |
| random_password = db_utils.generate_random_passwd() | |
| db_utils.send_passwd_in_email(self.auth_token, user_name_forgot_passwd, email_forgot_passwd, | |
| self.company_name, random_password) | |
| db_utils.change_passwd(user_log_in_database=user_login_table, | |
| email_forgot_passwd=email_forgot_passwd, | |
| random_password=random_password) | |
| st.success("Временный пароль выслан Вам на почту!") | |
| def reset_password() -> None: | |
| """ | |
| Creates the reset password widget and after user authentication | |
| (e-mail and the password shared over that e-mail), | |
| resets the password and updates the same in the _secret_auth_.json file. | |
| """ | |
| with st.form("Reset Password Form"): | |
| email_reset_passwd = st.text_input("Email", placeholder='Please enter your email') | |
| current_passwd = st.text_input("Временный пароль", | |
| placeholder='Введите пароль, который вы получили в письме') | |
| new_passwd = st.text_input("Новый пароль", placeholder='Введите новый пароль', | |
| type='password') | |
| new_passwd_1 = st.text_input("Повторите новый пароль", placeholder='Повторите пароль', | |
| type='password') | |
| reset_passwd_submit_button = st.form_submit_button(label='Изменить пароль') | |
| if reset_passwd_submit_button: | |
| email_exists_check, user_name_reset_passwd = db_utils.check_email_exists( | |
| user_log_in_database=user_login_table, | |
| email_forgot_passwd=email_reset_passwd) | |
| current_passwd_check = db_utils.check_current_passwd(user_log_in_database=user_login_table, | |
| email_reset_passwd=email_reset_passwd, | |
| current_passwd=current_passwd) | |
| if not email_exists_check: | |
| st.error("Пользователя с таким e-mail не существует!") | |
| elif not current_passwd_check: | |
| st.error("Неверный временный пароль!") | |
| elif new_passwd != new_passwd_1: | |
| st.error("Пароли не совпадают!") | |
| if email_exists_check and current_passwd_check: | |
| db_utils.change_passwd(user_log_in_database=user_login_table, | |
| email_forgot_passwd=email_reset_passwd, | |
| random_password=new_passwd) | |
| st.success("Пароль успешно изменен!") | |
| def logout_widget(self) -> None: | |
| """ | |
| Creates the logout widget in the sidebar only if the user is logged in. | |
| """ | |
| if st.session_state['LOGGED_IN']: | |
| del_logout = st.sidebar.empty() | |
| del_logout.markdown("#") | |
| logout_click_check = del_logout.button(self.logout_button_name) | |
| if logout_click_check: | |
| st.session_state['LOGOUT_BUTTON_HIT'] = True | |
| st.session_state['LOGGED_IN'] = False | |
| self.cookies['__streamlit_login_signup_ui_username__'] = '1c9a923f-fb21-4a91-b3f3-5f18e3f01182' | |
| del_logout.empty() | |
| st.rerun() | |
| def navigation(): | |
| """ | |
| Creates the side navigation bar | |
| """ | |
| selected_option = option_menu( | |
| menu_title='Навигация', | |
| menu_icon='list-columns-reverse', | |
| icons=['box-arrow-in-right', 'person-plus', 'x-circle', 'arrow-counterclockwise'], | |
| options=['Вход', login_call, 'Забыли пароль?', 'Восстановление пароля'], | |
| default_index=0, | |
| styles={ | |
| "container": {"padding": "10px", "text-align": "left"}, | |
| "nav-link": {"font-size": "16px", "text-align": "left", "margin": "0px"}}) | |
| return selected_option | |
| def hide_menu() -> None: | |
| """ | |
| Hides the streamlit menu situated in the top right. | |
| """ | |
| st.markdown(""" <style> | |
| #MainMenu {visibility: hidden;} | |
| </style> """, unsafe_allow_html=True) | |
| def hide_header() -> None: | |
| """ | |
| Hides the 'made with streamlit' footer. | |
| """ | |
| st.markdown(""" <style> | |
| header {visibility: hidden;} | |
| </style> """, unsafe_allow_html=True) | |
| def hide_footer() -> None: | |
| """ | |
| Hides the 'made with streamlit' footer. | |
| """ | |
| st.markdown(""" <style> | |
| footer {visibility: hidden;} | |
| </style> """, unsafe_allow_html=True) | |
| def build_login_ui(self): | |
| """ | |
| Brings everything together, calls important functions. | |
| """ | |
| if 'LOGGED_IN' not in st.session_state: | |
| st.session_state['LOGGED_IN'] = False | |
| if 'LOGOUT_BUTTON_HIT' not in st.session_state: | |
| st.session_state['LOGOUT_BUTTON_HIT'] = False | |
| selected_option = self.navigation() | |
| if selected_option == 'Вход': | |
| c1, c2 = st.columns([7, 3]) | |
| with c1: | |
| self.login_widget() | |
| with c2: | |
| if not st.session_state['LOGGED_IN']: | |
| pass | |
| # self.animation() | |
| if selected_option == login_call: | |
| self.sign_up_widget() | |
| if selected_option == 'Забыли пароль?': | |
| self.forgot_password() | |
| if selected_option == 'Восстановление пароля': | |
| self.reset_password() | |
| self.logout_widget() | |
| if st.session_state['LOGGED_IN']: | |
| pass | |
| if self.hide_menu_bool: | |
| self.hide_menu() | |
| if self.hide_footer_bool: | |
| self.hide_footer() | |
| return st.session_state['LOGGED_IN'] | |