Skip to content

Commit 20d3ab0

Browse files
committed
Initial Commit
1 parent 5ab4a4b commit 20d3ab0

6 files changed

Lines changed: 142 additions & 0 deletions

File tree

AppCreationScripts/sample.json

Whitespace-only changes.

app.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import uuid
2+
import flask
3+
import requests
4+
from flask import Flask, render_template, session, request
5+
from flask_session import Session
6+
import json
7+
import msal
8+
import sys
9+
import app_config
10+
11+
sess = Session()
12+
app = Flask(__name__)
13+
app.config.from_object('config.Config')
14+
sess.init_app(app)
15+
16+
config = json.load(open(sys.argv[1]))
17+
cache = msal.SerializableTokenCache()
18+
application = msal.ConfidentialClientApplication(
19+
app_config.CLIENT_ID, authority=app_config.AUTHORITY,
20+
client_credential=app_config.CLIENT_SECRET,
21+
token_cache=cache)
22+
23+
24+
def set_cache():
25+
if cache.has_state_changed:
26+
session[request.cookies.get("session")] = cache.serialize()
27+
28+
29+
@app.route('/')
30+
def index():
31+
# Initializing
32+
if (session.get(request.cookies.get("session"), '')) == '':
33+
session[request.cookies.get("session")] = ''
34+
cache.deserialize(session.get(request.cookies.get("session")))
35+
return render_template("index.html")
36+
37+
38+
@app.route('/authenticate')
39+
def authenticate():
40+
# Call to the authorize endpoint
41+
auth_state = str(uuid.uuid4())
42+
session['state'] = auth_state
43+
authorization_url = application.get_authorization_request_url(app_config.SCOPE, state=auth_state,
44+
redirect_uri=app_config.REDIRECT_URI)
45+
resp = flask.Response(status=307)
46+
resp.headers['location'] = authorization_url
47+
return resp
48+
49+
50+
@app.route("/getAToken")
51+
def main_logic():
52+
code = flask.request.args['code']
53+
state = flask.request.args['state']
54+
# Raising error if state does not match
55+
if state != session['state']:
56+
raise ValueError("State does not match")
57+
result = None
58+
# Checking token cache for accounts
59+
accounts = application.get_accounts()
60+
61+
# Trying to acquire token silently
62+
if accounts:
63+
result = application.acquire_token_silent(app_config.SCOPE, account=accounts[0])
64+
65+
# If silent call fails, fallback to acquireToken interactive call
66+
if not result:
67+
result = application.acquire_token_by_authorization_code(code, scopes=app_config.SCOPE,
68+
redirect_uri=app_config.REDIRECT_URI)
69+
# Updating cache
70+
set_cache()
71+
72+
# Using access token from result to call Microsoft Graph
73+
if 'access_token' not in result:
74+
return flask.redirect(flask.url_for('index'))
75+
endpoint = 'https://graph.microsoft.com/v1.0/me/'
76+
http_headers = {'Authorization': 'Bearer ' + result['access_token'],
77+
'User-Agent': 'msal-python-sample',
78+
'Accept': 'application/json',
79+
'Content-Type': 'application/json',
80+
'client-request-id': str(uuid.uuid4())}
81+
graph_data = requests.get(endpoint, headers=http_headers, stream=False).json()
82+
return flask.render_template('display.html', auth_result=graph_data)
83+
84+
85+
@app.route("/logout")
86+
def logout():
87+
# Logout
88+
accounts = application.get_accounts()
89+
application.remove_account(accounts[0])
90+
set_cache()
91+
return flask.redirect(flask.url_for('index'))
92+
93+
94+
if __name__ == "__main__":
95+
app.run()

app_config.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
TENANT = ""
2+
AUTHORITY = "https://login.microsoftonline.com/"+ TENANT
3+
CLIENT_ID = ""
4+
CLIENT_SECRET = ""
5+
SCOPE = "https://graph.microsoft.com/.default"
6+
REDIRECT_URI = "http://localhost:5000/getAToken"

config.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
class Config:
2+
"""Set Flask configuration vars from .env file."""
3+
4+
# General Config
5+
SECRET_KEY = 'super_secret_key'
6+
7+
# Flask-Session
8+
SESSION_TYPE = 'filesystem'

templates/display.html

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Acquire Token Result </title>
6+
</head>
7+
<body>
8+
<p1><b>Your information</b> </p1>
9+
<table>
10+
{% for key, value in auth_result.items() %}
11+
<tr>
12+
<th> {{ key }} </th>
13+
<td> {{ value }} </td>
14+
</tr>
15+
{% endfor %}
16+
</table>
17+
<form action="/logout" >
18+
<input type="submit" value=" Logout"/>
19+
</form>
20+
</body>
21+
</html>

templates/index.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Title</title>
6+
</head>
7+
<body>
8+
<form action="/authenticate" >
9+
<input type="submit" value="Get my info from graph"/>
10+
</form>
11+
</body>
12+
</html>

0 commit comments

Comments
 (0)