File size: 5,179 Bytes
001ea6a
76516dc
85964d8
76516dc
85964d8
76516dc
 
 
85964d8
 
 
8b139c7
85964d8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76516dc
 
 
 
85964d8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
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 = 'details.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)
    creds = flow.run_local_server(port=0)
    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()