awacke1 commited on
Commit
320f734
·
verified ·
1 Parent(s): f4e42f5

Rename app.py to Files.Backup.AuthWorksapp.py

Browse files
Files changed (2) hide show
  1. Files.Backup.AuthWorksapp.py +162 -0
  2. app.py +0 -209
Files.Backup.AuthWorksapp.py ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import streamlit as st
3
+ import requests
4
+ import msal
5
+ import urllib.parse
6
+ import base64
7
+ import hashlib
8
+ import secrets
9
+
10
+ # 🤓 Load environment variables (Ensure these are set!)
11
+ APPLICATION_ID_KEY = os.getenv('APPLICATION_ID_KEY')
12
+ CLIENT_SECRET_KEY = os.getenv('CLIENT_SECRET_KEY')
13
+ AUTHORITY_URL = 'https://login.microsoftonline.com/common'
14
+ REDIRECT_URI = 'https://huggingface.co/spaces/awacke1/MSGraphAPI'
15
+
16
+ # Define product to scope mapping
17
+ PRODUCT_SCOPES = {
18
+ "📧 Outlook": ['Mail.Read', 'Mail.Send', 'Calendars.ReadWrite'],
19
+ "📒 OneNote": ['Notes.Read', 'Notes.Create'],
20
+ "📊 Excel": ['Files.ReadWrite.All'],
21
+ "📄 Word": ['Files.ReadWrite.All'],
22
+ "🗃️ SharePoint": ['Sites.Read.All', 'Sites.ReadWrite.All'],
23
+ "📅 Teams": ['Team.ReadBasic.All', 'Channel.ReadBasic.All'],
24
+ "💬 Viva": ['Analytics.Read'],
25
+ "🚀 Power Platform": ['Flow.Read.All'],
26
+ "🧠 Copilot": ['Cognitive.Read'],
27
+ "🗂️ OneDrive": ['Files.ReadWrite.All'],
28
+ "💡 PowerPoint": ['Files.ReadWrite.All'],
29
+ "📚 Microsoft Bookings": ['Bookings.Read.All', 'Bookings.ReadWrite.All'],
30
+ "📓 Loop": ['Files.ReadWrite.All'],
31
+ "🗣️ Translator": ['Translation.Read'],
32
+ "📋 To Do & Planner": ['Tasks.ReadWrite'],
33
+ "🔗 Azure OpenAI Service": ['AzureAIServices.ReadWrite.All']
34
+ }
35
+
36
+ # Always include these base scopes
37
+ BASE_SCOPES = ['User.Read', 'openid', 'profile', 'offline_access']
38
+
39
+ # Function to generate PKCE code verifier and challenge
40
+ def generate_pkce_codes():
41
+ code_verifier = secrets.token_urlsafe(128)[:128]
42
+ code_challenge = base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode()).digest()).decode().rstrip('=')
43
+ return code_verifier, code_challenge
44
+
45
+ def get_msal_app(code_challenge=None):
46
+ return msal.PublicClientApplication(
47
+ client_id=APPLICATION_ID_KEY,
48
+ authority=AUTHORITY_URL
49
+ )
50
+
51
+ # Function to get access token
52
+ def get_access_token(code, code_verifier):
53
+ client_instance = get_msal_app()
54
+
55
+ try:
56
+ result = client_instance.acquire_token_by_authorization_code(
57
+ code=code,
58
+ scopes=st.session_state.get('scopes', BASE_SCOPES),
59
+ redirect_uri=REDIRECT_URI,
60
+ code_verifier=code_verifier
61
+ )
62
+
63
+ if 'access_token' in result:
64
+ return result['access_token']
65
+ else:
66
+ error_description = result.get('error_description', 'No error description provided')
67
+ raise Exception(f"Error acquiring token: {error_description}")
68
+ except Exception as e:
69
+ st.error(f"Exception in get_access_token: {str(e)}")
70
+ raise
71
+
72
+ # Main application function
73
+ def main():
74
+ st.title("🦄 MS Graph API with AI & Cloud Integration for M365")
75
+
76
+ # Sidebar for product selection
77
+ st.sidebar.title("📝 M365 Products")
78
+ st.sidebar.write("Select products to integrate:")
79
+
80
+ selected_products = {}
81
+ for product in PRODUCT_SCOPES.keys():
82
+ selected = st.sidebar.checkbox(product)
83
+ if selected:
84
+ selected_products[product] = True
85
+
86
+ # Dynamically build scopes based on selected products
87
+ scopes = BASE_SCOPES.copy()
88
+ for product in selected_products:
89
+ scopes.extend(PRODUCT_SCOPES[product])
90
+ scopes = list(set(scopes)) # Remove duplicates
91
+ st.session_state['scopes'] = scopes
92
+
93
+ # Authentication flow
94
+ if 'access_token' not in st.session_state:
95
+ if 'code_verifier' not in st.session_state:
96
+ code_verifier, code_challenge = generate_pkce_codes()
97
+ st.session_state['code_verifier'] = code_verifier
98
+ else:
99
+ code_verifier = st.session_state['code_verifier']
100
+ code_challenge = base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode()).digest()).decode().rstrip('=')
101
+
102
+ client_instance = get_msal_app()
103
+ auth_url = client_instance.get_authorization_request_url(
104
+ scopes=scopes,
105
+ redirect_uri=REDIRECT_URI,
106
+ code_challenge=code_challenge,
107
+ code_challenge_method="S256"
108
+ )
109
+ st.write('👋 Please [click here]({}) to log in and authorize the app.'.format(auth_url))
110
+
111
+ # Check for authorization code in query parameters
112
+ query_params = st.query_params
113
+ if 'code' in query_params:
114
+ code = query_params.get('code')
115
+ st.write('🔑 Authorization Code Obtained:', code[:10] + '...')
116
+
117
+ try:
118
+ access_token = get_access_token(code, code_verifier)
119
+ st.session_state['access_token'] = access_token
120
+ st.success("Access token acquired successfully!")
121
+ st.rerun()
122
+ except Exception as e:
123
+ st.error(f"Error acquiring access token: {str(e)}")
124
+ st.stop()
125
+ else:
126
+ # User is authenticated, proceed with the app
127
+ access_token = st.session_state['access_token']
128
+
129
+ # Greet the user
130
+ user_info = get_user_info(access_token)
131
+ if user_info:
132
+ st.sidebar.write(f"👋 Hello, {user_info.get('displayName', 'User')}!")
133
+
134
+ # Handle selected products
135
+ if selected_products:
136
+ st.header("🧩 M365 Product Integrations")
137
+ for product in selected_products:
138
+ st.subheader(f"{product}")
139
+ handle_product_integration(access_token, product)
140
+ else:
141
+ st.write("No products selected. Please select products from the sidebar.")
142
+
143
+ # Function to get user info
144
+ def get_user_info(access_token):
145
+ headers = {'Authorization': f'Bearer {access_token}'}
146
+ response = requests.get('https://graph.microsoft.com/v1.0/me', headers=headers)
147
+ if response.status_code == 200:
148
+ return response.json()
149
+ else:
150
+ st.error('Failed to fetch user info.')
151
+ return None
152
+
153
+ # Function to handle product integration
154
+ def handle_product_integration(access_token, product):
155
+ # Implement the integration logic for each product here
156
+ # This is a placeholder - you'll need to implement the actual API calls
157
+ st.write(f"Integrating {product}...")
158
+ # Example: if product == "📧 Outlook": get_outlook_data(access_token)
159
+
160
+ # Run the main function
161
+ if __name__ == "__main__":
162
+ main()
app.py DELETED
@@ -1,209 +0,0 @@
1
- import os
2
- import streamlit as st
3
- import requests
4
- import msal
5
- import secrets
6
- from urllib.parse import urlencode
7
- from datetime import datetime, timedelta
8
-
9
- # Configuration
10
- APPLICATION_ID = os.getenv('APPLICATION_ID_KEY')
11
- CLIENT_SECRET = os.getenv('CLIENT_SECRET_KEY')
12
- AUTHORITY = 'https://login.microsoftonline.com/common'
13
- REDIRECT_URI = 'https://huggingface.co/spaces/awacke1/MSGraphAPI'
14
- SCOPES = ['User.Read', 'Calendars.ReadWrite', 'Mail.ReadWrite', 'Files.ReadWrite.All']
15
-
16
- # MSAL setup
17
- def get_msal_app():
18
- return msal.ConfidentialClientApplication(
19
- client_id=APPLICATION_ID,
20
- client_credential=CLIENT_SECRET,
21
- authority=AUTHORITY
22
- )
23
-
24
- # Authentication functions
25
- def generate_auth_url():
26
- msal_app = get_msal_app()
27
- state = secrets.token_urlsafe(32)
28
- auth_url = msal_app.get_authorization_request_url(
29
- scopes=SCOPES,
30
- redirect_uri=REDIRECT_URI,
31
- state=state
32
- )
33
- new_query_params = st.query_params.to_dict()
34
- new_query_params['auth_state'] = state
35
- return f"{auth_url}&{urlencode(new_query_params)}"
36
-
37
- def get_token_from_code(code):
38
- msal_app = get_msal_app()
39
- result = msal_app.acquire_token_by_authorization_code(
40
- code=code,
41
- scopes=SCOPES,
42
- redirect_uri=REDIRECT_URI
43
- )
44
- if 'access_token' in result:
45
- return result
46
- else:
47
- raise Exception(f"Error acquiring token: {result.get('error_description')}")
48
-
49
- # API call function
50
- def make_api_call(endpoint, token, method='GET', data=None):
51
- headers = {'Authorization': f'Bearer {token}', 'Content-Type': 'application/json'}
52
- url = f'https://graph.microsoft.com/v1.0/{endpoint}'
53
-
54
- if method == 'GET':
55
- response = requests.get(url, headers=headers)
56
- elif method == 'POST':
57
- response = requests.post(url, headers=headers, json=data)
58
- else:
59
- raise ValueError(f"Unsupported method: {method}")
60
-
61
- if response.status_code in [200, 201]:
62
- return response.json()
63
- else:
64
- st.error(f"API call failed: {response.status_code} - {response.text}")
65
- return None
66
-
67
- # Product integration functions
68
- def handle_outlook_integration(token):
69
- st.subheader("📧 Outlook Integration")
70
- emails = make_api_call('me/messages?$top=5', token)
71
- if emails:
72
- for email in emails['value']:
73
- st.write(f"Subject: {email['subject']}")
74
- st.write(f"From: {email['from']['emailAddress']['name']}")
75
- st.write("---")
76
-
77
- def handle_onenote_integration(token):
78
- st.subheader("📒 OneNote Integration")
79
- notebooks = make_api_call('me/onenote/notebooks', token)
80
- if notebooks:
81
- for notebook in notebooks['value']:
82
- st.write(f"Notebook: {notebook['displayName']}")
83
-
84
- def handle_calendar_integration(token):
85
- st.subheader("📅 Calendar Integration")
86
- events = make_api_call('me/events?$top=5', token)
87
- if events:
88
- for event in events['value']:
89
- st.write(f"Event: {event['subject']}")
90
- st.write(f"Start: {event['start']['dateTime']}")
91
- st.write("---")
92
-
93
- def handle_onedrive_integration(token):
94
- st.subheader("🗂️ OneDrive Integration")
95
- files = make_api_call('me/drive/root/children', token)
96
- if files:
97
- for file in files['value']:
98
- st.write(f"File: {file['name']}")
99
- st.write(f"Type: {file['file']['mimeType'] if 'file' in file else 'Folder'}")
100
- st.write("---")
101
-
102
- # Main application
103
- def main():
104
- st.title("🦄 MS Graph API with AI & Cloud Integration for M365")
105
-
106
- # Debug information
107
- st.sidebar.write("Debug Info:")
108
- st.sidebar.write(f"Query Params: {st.query_params.to_dict()}")
109
-
110
- if 'code' in st.query_params and 'state' in st.query_params:
111
- received_state = st.query_params['state']
112
- expected_state = st.query_params.get('auth_state')
113
-
114
- if received_state != expected_state:
115
- st.error(f"Invalid state parameter. Expected {expected_state}, got {received_state}")
116
- st.error("Please try logging in again.")
117
- st.query_params.clear()
118
- st.rerun()
119
-
120
- try:
121
- token = get_token_from_code(st.query_params['code'])
122
- st.session_state['token'] = token
123
- st.query_params.clear()
124
- st.success("Successfully authenticated!")
125
- st.rerun()
126
- except Exception as e:
127
- st.error(f"Authentication failed: {str(e)}")
128
- st.query_params.clear()
129
- st.rerun()
130
-
131
- if 'token' not in st.session_state:
132
- auth_url = generate_auth_url()
133
- st.write("Please log in to continue:")
134
- st.markdown(f"[Login with Microsoft]({auth_url})")
135
- return
136
-
137
- # User is authenticated, show the main app
138
- token = st.session_state['token']['access_token']
139
- st.sidebar.success("Authenticated successfully!")
140
-
141
- # Display user info
142
- user_info = make_api_call('me', token)
143
- if user_info:
144
- st.sidebar.write(f"Welcome, {user_info.get('displayName', 'User')}!")
145
-
146
- # App navigation
147
- st.sidebar.title("Navigation")
148
- app_mode = st.sidebar.selectbox("Choose the app mode",
149
- ["Dashboard", "Product Integration", "Event Management"])
150
-
151
- if app_mode == "Dashboard":
152
- st.header("📊 Dashboard")
153
- # Add dashboard widgets here
154
-
155
- elif app_mode == "Product Integration":
156
- st.header("🧩 Product Integration")
157
- products = {
158
- "📧 Outlook": handle_outlook_integration,
159
- "📒 OneNote": handle_onenote_integration,
160
- "📅 Calendar": handle_calendar_integration,
161
- "🗂️ OneDrive": handle_onedrive_integration
162
- }
163
-
164
- for product, handler in products.items():
165
- if st.checkbox(f"Enable {product}"):
166
- handler(token)
167
-
168
- elif app_mode == "Event Management":
169
- st.header("📅 Event Management")
170
- event_action = st.radio("Choose an action", ["View Upcoming Events", "Add New Event"])
171
-
172
- if event_action == "View Upcoming Events":
173
- events = make_api_call('me/events?$top=10&$orderby=start/dateTime', token)
174
- if events:
175
- for event in events['value']:
176
- st.write(f"Event: {event['subject']}")
177
- st.write(f"Start: {event['start']['dateTime']}")
178
- st.write("---")
179
-
180
- elif event_action == "Add New Event":
181
- subject = st.text_input("Event Subject")
182
- start_date = st.date_input("Start Date")
183
- start_time = st.time_input("Start Time")
184
- duration = st.number_input("Duration (hours)", min_value=0.5, max_value=8.0, step=0.5)
185
-
186
- if st.button("Add Event"):
187
- start_datetime = datetime.combine(start_date, start_time)
188
- end_datetime = start_datetime + timedelta(hours=duration)
189
-
190
- event_data = {
191
- "subject": subject,
192
- "start": {
193
- "dateTime": start_datetime.isoformat(),
194
- "timeZone": "UTC"
195
- },
196
- "end": {
197
- "dateTime": end_datetime.isoformat(),
198
- "timeZone": "UTC"
199
- }
200
- }
201
-
202
- result = make_api_call('me/events', token, method='POST', data=event_data)
203
- if result:
204
- st.success("Event added successfully!")
205
- else:
206
- st.error("Failed to add event.")
207
-
208
- if __name__ == "__main__":
209
- main()