-
Notifications
You must be signed in to change notification settings - Fork 0
/
utility.py
159 lines (140 loc) · 5.75 KB
/
utility.py
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
157
158
159
import os
import logging
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
import streamlit as st
#from safe_constants import SCOPES, MAIN_REDIRECT_URI, ALL_REDIRECT_URIS, ALL_JAVASCRIPT_ORIGINS, PROJECT_ID, AUTH_URI, TOKEN_URI, AUTH_PROVIDER_X509_CERT_URL
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
from dotenv import load_dotenv
load_dotenv()
from safe_constants import SCOPES, MAIN_REDIRECT_URI, ALL_REDIRECT_URIS, ALL_JAVASCRIPT_ORIGINS
os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE'] = '1' # avoids error being thrown for duplicate scopes (doesn't matter for this use case)
from safe_constants import PROJECT_ID, AUTH_URI, TOKEN_URI, AUTH_PROVIDER_X509_CERT_URL
CLIENT_ID = st.secrets["GMAIL_API_CREDENTIALS"]["CLIENT_ID"]
CLIENT_SECRET = st.secrets["GMAIL_API_CREDENTIALS"]["CLIENT_SECRET"]
CLIENT_CONFIG = {
"web": {
"client_id": CLIENT_ID,
"project_id": PROJECT_ID,
"auth_uri": AUTH_URI,
"token_uri": TOKEN_URI,
"auth_provider_x509_cert_url": AUTH_PROVIDER_X509_CERT_URL,
"client_secret": CLIENT_SECRET,
"redirect_uris": ALL_REDIRECT_URIS,
"javascript_origins": ALL_JAVASCRIPT_ORIGINS
}
}
def get_user_info(creds):
# Build the OAuth2 service to get user info
oauth2_service = build('oauth2', 'v2', credentials=creds)
# Get user info
user_info = oauth2_service.userinfo().get().execute()
return user_info.get('email')
def authorize_gmail_api():
"""Shows basic usage of the Gmail API.
Lists the user's Gmail labels.
"""
creds = None
if os.path.exists("token.json"):
creds = Credentials.from_authorized_user_file("token.json", SCOPES)
st.info("Already logged in")
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_config(
CLIENT_CONFIG, SCOPES
)
flow.redirect_uri = MAIN_REDIRECT_URI
authorization_url, state = flow.authorization_url(
access_type='offline',
include_granted_scopes='true',
prompt='consent')
st.markdown(
f"""
<style>
.custom-button {{
display: inline-block;
background-color: #4CAF50; /* Green background */
color: white !important; /* White text */
padding: 10px 24px;
text-align: center;
text-decoration: none;
font-size: 16px;
border-radius: 5px;
margin-top: 5px; /* Reduce space above the button */
margin-bottom: 5px; /* Reduce space below the button */
}}
.custom-button:hover {{
background-color: #45a049;
}}
</style>
<a href="{authorization_url}" target="_blank" class="custom-button">Authorize with Google</a>
""",
unsafe_allow_html=True
)
def authenticate_user():
"""after logging in with google, you have a code in the url. This function retrieves the code and fetches the credentials and authenticates user"""
auth_code = st.query_params.get('code', None)
if auth_code is not None:
logger.debug("INSIDE CODE")
try:
from utility import CLIENT_CONFIG
# make a new flow to fetch tokens
flow = InstalledAppFlow.from_client_config(
CLIENT_CONFIG, SCOPES,
)
flow.redirect_uri = MAIN_REDIRECT_URI
flow.fetch_token(code=auth_code)
st.query_params.clear()
creds = flow.credentials
if creds:
st.session_state.creds = creds
# Save the credentials for future use
with open('token.json', 'w') as token_file:
token_file.write(creds.to_json())
st.success("Authorization successful! Credentials have been saved.")
# Save the credentials for the next run
with open("token.json", "w") as token:
token.write(creds.to_json())
# get user email
user_email = get_user_info(creds)
st.session_state.user_email = user_email
#st.experimental_set_query_params()
st.rerun()
except Exception as e:
logger.error(f"Error authenticating user: {e}")
st.error("Failed to authenticate user. Please try again.")
else:
st.error("Could not log in user")
def switch_account(selected_email):
"""
Switch to the selected Gmail account.
Args:
selected_email (str): The email address of the account to switch to.
Returns:
None
"""
if selected_email in st.session_state.tokens:
st.query_params.clear()
st.session_state.creds = st.session_state.tokens[selected_email]
st.session_state.user_email = selected_email
else:
st.error("Account not authorized. Please log in.")
def store_token(email, creds):
"""
Store the OAuth token for a Gmail account.
Args:
email (str): The email address of the account.
creds: The OAuth credentials.
Returns:
None
"""
logger.debug("INSIDE STORE TOKEN")
if "tokens" not in st.session_state:
st.session_state.tokens = {}
st.session_state.tokens[email] = creds