import streamlit as st from google_auth_oauthlib.flow import InstalledAppFlow from googleapiclient.discovery import build from google.auth.transport.requests import Request from googleapiclient.errors import HttpError import pickle import os import hashlib # Constants CREDS_FILE = 'token.pickle' CREDENTIALS_FILE = 'webapp.json' SCOPES = ['https://www.googleapis.com/auth/spreadsheets'] SPREADSHEET_ID = "17KIBySu21Oh0ajtyo4A9jUTjnwOIl69KlqNlTfszrXQ" RANGE_NAME = "Sheet1!A:C" # Google Sheets API setup with OAuth def get_gsheet_service(creds): try: service = build('sheets', 'v4', credentials=creds) return service except HttpError as err: st.error(f"Failed to create service: {err}") return None def append_data_to_sheet(service, spreadsheet_id, range_name, values): try: body = { 'values': values } result = service.spreadsheets().values().append( spreadsheetId=spreadsheet_id, range=range_name, valueInputOption="RAW", body=body ).execute() return result except HttpError as err: st.error(f"Failed to append data: {err}") return None def read_data_from_sheet(service, spreadsheet_id, range_name): try: result = service.spreadsheets().values().get(spreadsheetId=spreadsheet_id, range=range_name).execute() return result.get('values', []) except HttpError as err: st.error(f"Failed to read data: {err}") return [] # Function to hash passwords def hash_password(password): return hashlib.sha256(password.encode()).hexdigest() # OAuth flow setup def get_credentials(): if os.path.exists(CREDS_FILE): with open(CREDS_FILE, 'rb') as token: creds = pickle.load(token) if creds and creds.valid: return creds if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) with open(CREDS_FILE, 'wb') as token: pickle.dump(creds, token) return creds flow = InstalledAppFlow.from_client_secrets_file(CREDENTIALS_FILE, SCOPES) # Use run_console instead of run_local_server creds = flow.run_console() with open(CREDS_FILE, 'wb') as token: pickle.dump(creds, token) return creds # Sign Up Page def signup(service): st.subheader("Sign Up") with st.form(key='signup_form'): new_username = st.text_input("Username") new_password = st.text_input("Password", type="password") signup_button = st.form_submit_button("Sign Up") if signup_button: if new_username and new_password: # Check if username already exists user_data = read_data_from_sheet(service, SPREADSHEET_ID, RANGE_NAME) for user in user_data: if user[0] == new_username: st.error("Username already exists. Please choose a different username.") return # Hash the password hashed_password = hash_password(new_password) # Store the username and hashed password values = [[new_username, hashed_password]] result = append_data_to_sheet(service, SPREADSHEET_ID, RANGE_NAME, values) if result: st.success("Signup successful! Please go to the login page.") else: st.error("Failed to sign up.") else: st.error("Please provide both a username and password.") # Login Page def login(service): st.subheader("Login") with st.form(key='login_form'): username = st.text_input("Username") password = st.text_input("Password", type="password") login_button = st.form_submit_button("Login") if login_button: if username and password: # Hash the password hashed_password = hash_password(password) # Read data from Google Sheets user_data = read_data_from_sheet(service, SPREADSHEET_ID, RANGE_NAME) # Verify login credentials for user in user_data: if user[0] == username and user[1] == hashed_password: st.success("Login successful!") return True st.error("Invalid username or password.") else: st.error("Please enter both username and password.") return False # Streamlit app def main(): st.title("Google Sheets Authentication System") # Get OAuth credentials creds = get_credentials() # Create a service object service = get_gsheet_service(creds) if service: # Choose between login and signup page = st.sidebar.selectbox("Choose a page", ["Login", "Signup"]) if page == "Login": logged_in = login(service) if logged_in: st.write("You are logged in! You can add more functionality here.") elif page == "Signup": signup(service) else: st.error("Failed to create the service.") if __name__ == "__main__": main()