commit 1bdd42fef5ad2bd55aa4d27a49811ae4efcc10de Author: pstruebi Date: Sun Jun 12 10:39:42 2022 +0200 initial commit diff --git a/app.py b/app.py new file mode 100644 index 0000000..e41ef65 --- /dev/null +++ b/app.py @@ -0,0 +1,38 @@ +import sqlite3 + +from flask import Flask, render_template, request, url_for, flash, redirect +from werkzeug.exceptions import abort + + +def get_db_connection(): + conn = sqlite3.connect('database.db') + conn.row_factory = sqlite3.Row + return conn + +def get_post(post_id): + conn = get_db_connection() + post = conn.execute('SELECT * FROM posts WHERE id = ?', + (post_id,)).fetchone() + conn.close() + if post is None: + abort(404) + return post + + +app = Flask(__name__) +# app.config['SECRET_KEY'] = 'hello' + +@app.route('/') +def index(): + conn = get_db_connection() + posts = conn.execute('SELECT * FROM posts').fetchall() + conn.close() + + return render_template('index.html', posts=posts) + +@app.route('/') +def post(post_id): + post = get_post(post_id) + return render_template('calendar.html', post=post) + + diff --git a/calendar_interface.py b/calendar_interface.py new file mode 100644 index 0000000..7ff7d79 --- /dev/null +++ b/calendar_interface.py @@ -0,0 +1,82 @@ + +import json +from lib2to3.pgen2.tokenize import TokenError +import logging + +import requests +import msal + +config = { + "authority": "https://login.microsoftonline.com/propedal.at", + "client_id": "52f192c4-875d-44a2-b28a-575e920225e5", # client public id (from azure web interface)#"da3fc28c-5fcf-4884-9477-903a4420cc3d", + "scope": ["https://graph.microsoft.com/.default"], # scopes from api + "secret": "irj8Q~PliZzSe7JnXEaiWKQ6v0CAg1DTZOO~Ccsf" # api secret key (from azure web interface)#"bqP8Q~SEp_AmYYDZoEykXxZdADoCOhzOOhbO3c3T" +} +USER_ID = "simone.profus@propedal.at" # user with calendar #"2af02ca1-77fc-46fd-90af-c754306081cb" # +CALENDAR_ID = "AAMkADY0MDg1MTVjLTg5ZjItNGQxYS04MGQ3LWY2NjJmYjM0YmZhOQBGAAAAAADXD7SdVoWYQI4RYXbBumMEBwAf_ngZxs71RonY3GuLL8TVAAAAAAEGAAAf_ngZxs71RonY3GuLL8TVAADHFxN2AAA=" # calendar id - determined by /users/id/calendars + +# Optional logging +logging.basicConfig(format='%(asctime)s,%(msecs)d %(levelname)-4s [%(filename)s:%(lineno)d] %(message)s', + datefmt='%Y-%m-%d:%H:%M:%S', + level=logging.INFO) +# logging.getLogger("msal").setLevel(logging.INFO) # Optionally disable MSAL DEBUG logs + +def get_access_token(): + #with open("auth_config.json") as f: + # config = json.load(f) + + # Create a preferably long-lived app instance which maintains a token cache. + app = msal.ConfidentialClientApplication( + config["client_id"], authority=config["authority"], + client_credential=config["secret"], + # token_cache=... # Default cache is in memory only. + # You can learn how to use SerializableTokenCache from + # https:#msal-python.readthedocs.io/en/latest/#msal.SerializableTokenCache + ) + + # The pattern to acquire a token looks like this. + result = None + + # Firstly, looks up a token from cache + # Since we are looking for token for the current app, NOT for an end user, + # notice we give account parameter as None. # TODO: token never exists in cache; make app long living + result = app.acquire_token_silent(config["scope"], account=None) + + if result is None: + logging.info("No suitable token exists in cache. Let's get a new one from AAD.") + return app.acquire_token_for_client(scopes=config["scope"]) + else: + logging.info("Token was found in cache.") + + if not "access_token" in result: # a final check + logging.error(result.get("error")) + logging.error(result.get("error_description")) + logging.error(result.get("correlation_id")) # You may need this when reporting a bug + raise TokenError() + + return result + + +def execute_request(token: dict, endpoint:str): + return requests.get( # Use token to call downstream service + endpoint, + headers={'Authorization': 'Bearer ' + token['access_token']},).json() + +def execute_user_request(token, endpoint, user_id=USER_ID): + return execute_request(token, "https://graph.microsoft.com/v1.0/users/" + user_id + f"/{endpoint}") + + +if __name__ == "__main__": + # Calling graph using the access token + token = get_access_token() + + calendars = execute_user_request(token, "calendars") + cal_name_id = [(c["name"], c["id"]) for c in calendars["value"]] + + print("Available calendars are:") + print(json.dumps(cal_name_id, indent=2)) + + print("Events in selected calendar are:") + events = execute_user_request(token, f"calendars/{CALENDAR_ID}/events").get("value") + print(json.dumps(events, indent=2)) + diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..40494b0 --- /dev/null +++ b/templates/base.html @@ -0,0 +1,43 @@ + + + + + + + + + + + {% block title %} {% endblock %} + + + +
+ {% for message in get_flashed_messages() %} +
{{ message }}
+ {% endfor %} + {% block content %} {% endblock %} +
+ + + + + + + + \ No newline at end of file diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..8dbacea --- /dev/null +++ b/templates/index.html @@ -0,0 +1,17 @@ + + +{% block content %} +

{% block title %} Welcome to FlaskBlog {% endblock %}

+ {% for post in posts %} + +

{{ post['title'] }}

+
+ {{ post['created'] }} + + + Edit + +
+ + {% endfor %} +{% endblock %} \ No newline at end of file diff --git a/templates/post.html b/templates/post.html new file mode 100644 index 0000000..2fcc4b0 --- /dev/null +++ b/templates/post.html @@ -0,0 +1,7 @@ +{% extends 'base.html' %} + +{% block content %} +

{% block title %} {{ post['title'] }} {% endblock %}

+ {{ post['created'] }} +

{{ post['content'] }}

+{% endblock %} \ No newline at end of file