File size: 4,562 Bytes
921344f
 
 
 
 
a35b868
 
921344f
a35b868
 
 
 
 
 
921344f
a35b868
 
 
 
 
 
 
921344f
a35b868
 
 
 
 
 
 
 
 
 
 
 
 
ec81794
a35b868
 
 
 
 
 
b513742
a35b868
 
 
 
b513742
a35b868
 
 
 
 
 
 
 
 
ec81794
a35b868
 
 
ec81794
a35b868
 
 
a81cb6d
a35b868
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a78ffeb
a35b868
 
 
 
 
b513742
a35b868
 
 
 
 
 
 
 
b513742
a35b868
 
 
 
 
921344f
a35b868
 
 
 
 
 
 
b513742
a35b868
 
 
 
 
 
 
b513742
a35b868
 
 
 
 
 
 
921344f
 
a35b868
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
import os
import streamlit as st
import requests
import msal
import secrets
import time
from urllib.parse import urlencode

# Configuration
APPLICATION_ID = os.getenv('APPLICATION_ID_KEY')
CLIENT_SECRET = os.getenv('CLIENT_SECRET_KEY')
AUTHORITY = 'https://login.microsoftonline.com/common'
REDIRECT_URI = 'https://huggingface.co/spaces/awacke1/MSGraphAPI'
SCOPES = ['User.Read', 'Calendars.ReadWrite', 'Mail.ReadWrite']

# MSAL setup
def get_msal_app():
    return msal.ConfidentialClientApplication(
        client_id=APPLICATION_ID,
        client_credential=CLIENT_SECRET,
        authority=AUTHORITY
    )

# Authentication functions
def generate_auth_url():
    msal_app = get_msal_app()
    state = secrets.token_urlsafe(32)
    auth_url = msal_app.get_authorization_request_url(
        scopes=SCOPES,
        redirect_uri=REDIRECT_URI,
        state=state
    )
    # Store the state in query params
    new_query_params = st.query_params.to_dict()
    new_query_params['auth_state'] = state
    return f"{auth_url}&{urlencode(new_query_params)}"

def get_token_from_code(code):
    msal_app = get_msal_app()
    result = msal_app.acquire_token_by_authorization_code(
        code=code,
        scopes=SCOPES,
        redirect_uri=REDIRECT_URI
    )
    if 'access_token' in result:
        return result
    else:
        raise Exception(f"Error acquiring token: {result.get('error_description')}")

# API call function
def make_api_call(endpoint, token):
    headers = {'Authorization': f'Bearer {token}'}
    response = requests.get(f'https://graph.microsoft.com/v1.0/{endpoint}', headers=headers)
    if response.status_code == 200:
        return response.json()
    else:
        st.error(f"API call failed: {response.status_code} - {response.text}")
        return None

# Main application
def main():
    st.title("๐Ÿฆ„ MS Graph API Integration")

    # Debug information
    st.sidebar.write("Debug Info:")
    st.sidebar.write(f"Query Params: {st.query_params.to_dict()}")

    if 'code' in st.query_params and 'state' in st.query_params:
        received_state = st.query_params['state']
        expected_state = st.query_params.get('auth_state')
        
        if received_state != expected_state:
            st.error(f"Invalid state parameter. Expected {expected_state}, got {received_state}")
            st.error("Please try logging in again.")
            st.query_params.clear()
            st.rerun()
        
        try:
            token = get_token_from_code(st.query_params['code'])
            st.session_state['token'] = token
            st.query_params.clear()
            st.success("Successfully authenticated!")
            st.rerun()
        except Exception as e:
            st.error(f"Authentication failed: {str(e)}")
            st.query_params.clear()
            st.rerun()

    if 'token' not in st.session_state:
        auth_url = generate_auth_url()
        st.write("Please log in to continue:")
        st.markdown(f"[Login with Microsoft]({auth_url})")
        return

    # User is authenticated, show the main app
    token = st.session_state['token']
    st.sidebar.success("Authenticated successfully!")
    
    # Display user info
    user_info = make_api_call('me', token['access_token'])
    if user_info:
        st.sidebar.write(f"Welcome, {user_info.get('displayName', 'User')}!")

    # App functionality
    option = st.sidebar.selectbox(
        "Choose a function",
        ["View Emails", "View Calendar", "View OneDrive Files"]
    )

    if option == "View Emails":
        emails = make_api_call('me/messages?$top=10', token['access_token'])
        if emails:
            for email in emails['value']:
                st.write(f"Subject: {email['subject']}")
                st.write(f"From: {email['from']['emailAddress']['name']}")
                st.write("---")

    elif option == "View Calendar":
        events = make_api_call('me/events?$top=10', token['access_token'])
        if events:
            for event in events['value']:
                st.write(f"Event: {event['subject']}")
                st.write(f"Start: {event['start']['dateTime']}")
                st.write("---")

    elif option == "View OneDrive Files":
        files = make_api_call('me/drive/root/children', token['access_token'])
        if files:
            for file in files['value']:
                st.write(f"File: {file['name']}")
                st.write(f"Type: {file['file']['mimeType'] if 'file' in file else 'Folder'}")
                st.write("---")

if __name__ == "__main__":
    main()