Spaces:
Running
Running
File size: 5,673 Bytes
921344f a13b66a 921344f a13b66a 921344f a13b66a 921344f a13b66a ec81794 a13b66a b513742 a13b66a ec81794 a13b66a ec81794 a13b66a a81cb6d a13b66a a78ffeb a13b66a b513742 a13b66a b513742 a13b66a 921344f a13b66a b513742 a13b66a b513742 a13b66a 921344f a13b66a 921344f a13b66a |
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 |
import os
import streamlit as st
import requests
import msal
import base64
import hashlib
import secrets
# π€ Load environment variables (Ensure these are set!)
APPLICATION_ID_KEY = os.getenv('APPLICATION_ID_KEY')
CLIENT_SECRET_KEY = os.getenv('CLIENT_SECRET_KEY')
AUTHORITY_URL = 'https://login.microsoftonline.com/common' # Use 'common' for multi-tenant apps
REDIRECT_URI = 'https://huggingface.co/spaces/awacke1/MSGraphAPI' # Update this to match your app's redirect URI
# π― Define the scopes your app will need
SCOPES = ['User.Read']
# New function to generate PKCE code verifier and challenge
def generate_pkce_codes():
code_verifier = secrets.token_urlsafe(128)[:128]
code_challenge = base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode()).digest()).decode().rstrip('=')
return code_verifier, code_challenge
# π οΈ Initialize the MSAL client for Public Client App (PKCE support)
def get_msal_app():
return msal.PublicClientApplication(
client_id=APPLICATION_ID_KEY,
authority=AUTHORITY_URL
)
# π Acquire access token using authorization code
def get_access_token(code, code_verifier=None):
client_instance = get_msal_app()
st.write("Debug: MSAL App Configuration:")
st.write(f"Client ID: {APPLICATION_ID_KEY[:5]}...")
st.write(f"Authority: {AUTHORITY_URL}")
st.write(f"Redirect URI: {REDIRECT_URI}")
try:
# Attempt to acquire token, use PKCE code_verifier if provided
result = client_instance.acquire_token_by_authorization_code(
code=code,
scopes=SCOPES,
redirect_uri=REDIRECT_URI,
code_verifier=code_verifier # Include only if PKCE is enabled
)
if 'access_token' in result:
return result['access_token']
else:
error_description = result.get('error_description', 'No error description provided')
raise Exception(f"Error acquiring token: {error_description}")
except Exception as e:
st.error(f"Exception in get_access_token: {str(e)}")
raise
# πββοΈ Main function to process the query parameters and handle the token exchange
def process_query_params():
try:
query_params = st.experimental_get_query_params()
st.write("Debug: All query parameters:", query_params)
if 'error' in query_params:
error = query_params.get('error')
error_description = query_params.get('error_description', 'No description provided')
st.error(f"Authentication Error: {error}")
st.error(f"Error Description: {error_description}")
st.stop()
if 'code' in query_params:
code = query_params.get('code')[0] # MS Graph returns the code as a list
st.write('π Authorization Code Obtained:', code[:10] + '...')
try:
# Retrieve code_verifier from session state
code_verifier = st.session_state.get('code_verifier')
if not code_verifier:
st.error("Code verifier not found in session state.")
st.stop()
# Acquire the access token
access_token = get_access_token(code, code_verifier)
st.session_state['access_token'] = access_token
st.success("Access token acquired successfully!")
# Clear the query parameters from the URL
st.experimental_set_query_params()
st.experimental_rerun()
except Exception as e:
st.error(f"Error acquiring access token: {str(e)}")
st.stop()
else:
st.warning("No authorization code found in the query parameters.")
except Exception as e:
st.error(f"Error processing query parameters: {str(e)}")
st.stop()
# Main application function
def main():
st.title("π¦ MS Graph API with AI & Cloud Integration with M365")
if 'access_token' not in st.session_state:
if 'code_verifier' not in st.session_state:
# Generate PKCE codes and store code_verifier in session
code_verifier, code_challenge = generate_pkce_codes()
st.session_state['code_verifier'] = code_verifier
else:
code_verifier = st.session_state['code_verifier']
code_challenge = base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode()).digest()).decode().rstrip('=')
# Get MSAL app and construct the authorization URL
client_instance = get_msal_app()
auth_url = client_instance.get_authorization_request_url(
scopes=SCOPES,
redirect_uri=REDIRECT_URI,
code_challenge=code_challenge,
code_challenge_method="S256"
)
st.write('π Please [click here]({}) to log in and authorize the app.'.format(auth_url))
st.stop()
# Process query parameters to acquire token
process_query_params()
# If access token is present, greet the user
if 'access_token' in st.session_state:
access_token = st.session_state['access_token']
headers = {'Authorization': 'Bearer ' + access_token}
response = requests.get('https://graph.microsoft.com/v1.0/me', headers=headers)
if response.status_code == 200:
user_info = response.json()
st.write(f"π Hello, {user_info['displayName']}!")
else:
st.error("Failed to fetch user info.")
st.write(response.text)
# π Run the main function
if __name__ == "__main__":
main()
|