put app configurations in config.py

This commit is contained in:
pstruebi
2022-06-15 09:30:45 +02:00
parent cd89ee2b8b
commit ec1946b2e7
6 changed files with 73 additions and 37 deletions

11
app.py
View File

@@ -1,3 +1,4 @@
import os
import logging
import json
@@ -8,9 +9,13 @@ import calendar_interface
import db
import auth
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
)
app = Flask(__name__)
app.config['SECRET_KEY'] = '\xacI4\x077\x16?Q\xb4")\xdb\x066\x95\x11i\x0b\x0c&\xb6rP\''
app.config['SECURITY_PASSWORD_SALT'] = '>\xe3\x9bz\xfd\xbc[\xe22\xcfK\xca\x88!\xd8\xd5,\xd0\x95\x0c\x02\xad\xfa\x9d'
app.config.from_object(os.environ["CONFIG"])# load config, pointed to by env var
app.teardown_appcontext(db.close_db)
app.cli.add_command(db.init_db_command)
@@ -28,7 +33,7 @@ def index():
else:
return render_template('index.html', events=events, user=g.user)
# @app.route('/<int:event_id>')
# @app.route('/<int:event_id>') # TODO: access detailed event view
# def post(post_id):
# post = get_post(post_id)
# return render_template('show_event.html', post=post)

12
auth.py
View File

@@ -3,13 +3,12 @@ import functools
import logging
from flask import (
Blueprint, flash, g, redirect, render_template, request, session, url_for
Blueprint, flash, g, redirect, render_template, request, session, url_for, current_app
)
from werkzeug.security import check_password_hash, generate_password_hash
from itsdangerous import URLSafeTimedSerializer
from db import get_db
import app
import calendar_interface
bp = Blueprint('auth', __name__, url_prefix='/auth')
@@ -120,16 +119,16 @@ def login_required(view): # use this as decorator
def generate_confirmation_token(email):
serializer = URLSafeTimedSerializer(app.app.config['SECRET_KEY'])
return serializer.dumps(email, salt=app.app.config['SECURITY_PASSWORD_SALT'])
serializer = URLSafeTimedSerializer(current_app.config['SECRET_KEY'])
return serializer.dumps(email, salt=current_app.config['SECURITY_PASSWORD_SALT'])
def confirm_token(token, expiration=3600*14*28): # 2 Wochen expiration
serializer = URLSafeTimedSerializer(app.app.config['SECRET_KEY'])
serializer = URLSafeTimedSerializer(current_app.config['SECRET_KEY'])
try:
email = serializer.loads(
token,
salt=app.app.config['SECURITY_PASSWORD_SALT'],
salt=current_app.config['SECURITY_PASSWORD_SALT'],
max_age=expiration
)
except:
@@ -138,7 +137,6 @@ def confirm_token(token, expiration=3600*14*28): # 2 Wochen expiration
@bp.route('/confirm/<token>')
# @login_required # TODO: notwendig? security ?
def confirm_email(token):
try:
email = confirm_token(token)

View File

@@ -5,37 +5,24 @@ import argparse
import requests
import msal
from config import MsalConfig
try:
from zoneinfo import ZoneInfo
except ImportError:
from backports.zoneinfo import ZoneInfo
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
WEEKDAYS= {0:"Mo", 1:"Di", 2:"Mi", 3:"Do", 4: "Fr", 5:"Sa", 6: "So"}
# 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"],
MsalConfig.CLIENT_ID, authority=MsalConfig.AUTHORITY,
client_credential=MsalConfig.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
@@ -47,11 +34,11 @@ def get_access_token():
# 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)
result = app.acquire_token_silent(MsalConfig.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"])
return app.acquire_token_for_client(scopes=MsalConfig.SCOPE)
else:
logging.info("Token was found in cache.")
@@ -82,7 +69,7 @@ def execute_patch_request(token, endpoint, data):
#data=data,
headers={'Authorization': 'Bearer ' + token['access_token']},).json()
def send_mail(to, subject, content, user_id=USER_ID):
def send_mail(to, subject, content, user_id=MsalConfig.USER_ID):
token=get_access_token()
@@ -106,24 +93,24 @@ def send_mail(to, subject, content, user_id=USER_ID):
return execute_post_request(token, "https://graph.microsoft.com/v1.0/users/" + user_id + "/sendMail", mail)
def update_calendar_event(event_id, data, user_id=USER_ID):
def update_calendar_event(event_id, data, user_id=MsalConfig.USER_ID):
token = get_access_token()
endpoint= "https://graph.microsoft.com/v1.0/users/" + user_id + f"/calendar/events/{event_id}"
return execute_patch_request(token, endpoint, data)
def execute_user_request(token, endpoint, user_id=USER_ID):
def execute_user_request(token, endpoint, user_id=MsalConfig.USER_ID):
return execute_get_request(token, "https://graph.microsoft.com/v1.0/users/" + user_id + f"/{endpoint}")
def get_all_calendar_events():
token = get_access_token()
return execute_user_request(token, f"calendars/{CALENDAR_ID}/events").get("value")
return execute_user_request(token, f"calendars/{MsalConfig.CALENDAR_ID}/events").get("value")
def get_calendar_event(id, filter: str=""):
token = get_access_token()
return execute_user_request(token, f"calendars/{CALENDAR_ID}/events/{id}{filter}")
return execute_user_request(token, f"calendars/{MsalConfig.CALENDAR_ID}/events/{id}{filter}")
def get_future_calendar_events():
@@ -137,7 +124,7 @@ def get_future_calendar_events():
token = get_access_token()
return execute_user_request(token, f"calendars/{CALENDAR_ID}/calendarview{filter}")
return execute_user_request(token, f"calendars/{MsalConfig.CALENDAR_ID}/calendarview{filter}")
def convert_datetimes(events):
for event in events:
@@ -181,6 +168,10 @@ def delte_attendee(data, email):
if __name__ == "__main__":
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)
parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('--show_calendars', help='Show available calendars', action='store_true')
parser.add_argument('--show_event_entries', help='Show available event fields', action='store_true')

42
config.py Normal file
View File

@@ -0,0 +1,42 @@
class DefaultConfig:
DEBUG = False
TESTING = False
DATABASE_URI = "users.db"
SECRET_KEY = SECURITY_PASSWORD_SALT='default'
class Config(DefaultConfig):
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"
CALENDAR_ID = "AAMkADY0MDg1MTVjLTg5ZjItNGQxYS04MGQ3LWY2NjJmYjM0YmZhOQBGAAAAAADXD7SdVoWYQI4RYXbBumMEBwAf_ngZxs71RonY3GuLL8TVAAAAAAEGAAAf_ngZxs71RonY3GuLL8TVAADHFxN2AAA=" # calendar id - determined by /users/id/calendars
class ProductionConfig(Config):
SECRET_KEY = '\xacI4\x077\x16?Q\xb4")\xdb\x066\x95\x11i\x0b\x0c&\xb6rP\''
SECURITY_PASSWORD_SALT = '>\xe3\x9bz\xfd\xbc[\xe22\xcfK\xca\x88!\xd8\xd5,\xd0\x95\x0c\x02\xad\xfa\x9d'
DATABASE_URI = 'mysql://user@localhost/foo'
class DevelopmentConfig(Config):
DEBUG = True
class TestingConfig(Config):
TESTING = True
class MsalDefaulConfig():
AUTHORITY = "https://login.microsoftonline.com/common"
SCOPE = ["https://graph.microsoft.com/.default"] # scopes from api
CLIENT_ID = "" # client public id (from azure web interface)
SECRET = "" # api secret key (from azure web interface)
USER_ID = "user@domain"
CALENDAR_ID = "" # calendar id - determined by /users/id/calendars
class MsalConfig(MsalDefaulConfig):
AUTHORITY = "https://login.microsoftonline.com/propedal.at"
CLIENT_ID = "52f192c4-875d-44a2-b28a-575e920225e5" # client public id (from azure web interface)
SECRET = "irj8Q~PliZzSe7JnXEaiWKQ6v0CAg1DTZOO~Ccsf" # api secret key (from azure web interface)
USER_ID = "simone.profus@propedal.at"
CALENDAR_ID = "AAMkADY0MDg1MTVjLTg5ZjItNGQxYS04MGQ3LWY2NjJmYjM0YmZhOQBGAAAAAADXD7SdVoWYQI4RYXbBumMEBwAf_ngZxs71RonY3GuLL8TVAAAAAAEGAAAf_ngZxs71RonY3GuLL8TVAADHFxN2AAA=" # calendar id - determined by /users/id/calendars

3
db.py
View File

@@ -4,12 +4,11 @@ import click
from flask import current_app, g
from flask.cli import with_appcontext
DATABASE_PATH = "users.db"
def get_db():
if 'db' not in g:
g.db = sqlite3.connect(
DATABASE_PATH,
current_app.config["DATABASE_URI"],
detect_types=sqlite3.PARSE_DECLTYPES
)
g.db.row_factory = sqlite3.Row

View File

@@ -1,2 +1,3 @@
export FLASK_ENV=development
export CONFIG=config.DevelopmentConfig
flask run --host=0.0.0.0