import os from flask import Flask, render_template, request, redirect, abort import requests def get_env_variable(var_name): value = os.environ.get(var_name) if not value: raise ValueError(f"Missing required environment variable: {var_name}") return value app = Flask(__name__) # Read environment variables outside the route function client_id = get_env_variable('CLIENT_ID') redirect_uri = get_env_variable('REDIRECT_URI') optional_scopes = get_env_variable('OPTIONAL_SCOPES') database_url = get_env_variable('DATABASE_URL') csrf_protection_string = None @app.route('/') def home(): if is_logged_in(): return render_template('success.html') # Generate a CSRF protection string global csrf_protection_string csrf_protection_string = os.urandom(16).hex() # Pass dynamic variables to the template return render_template('index.html', client_id=client_id, redirect_uri=redirect_uri, optional_scopes=optional_scopes, csrf_protection_string=csrf_protection_string) @app.route('/oauth-redirect') def oauth_redirect(): auth_code = request.args.get('code') csrf_token = request.args.get('state') # Verify the CSRF protection string if csrf_token != csrf_protection_string: abort(400, 'Invalid CSRF token. Please try again.') # Exchange authorization code for access and refresh tokens response = requests.post( 'https://www.inoreader.com/oauth2/token', headers={ 'Content-Type': 'application/x-www-form-urlencoded', 'User-agent': 'your-user-agent' }, data={ 'code': auth_code, 'redirect_uri': get_env_variable('REDIRECT_URI'), 'client_id': get_env_variable('CLIENT_ID'), 'client_secret': get_env_variable('CLIENT_SECRET'), 'scope': '', 'grant_type': 'authorization_code' } ) response.raise_for_status() tokens = response.json() # Save tokens for later use save_tokens(tokens['access_token'], tokens['refresh_token'], tokens['expires_in']) return redirect('/') def is_logged_in(): response = requests.get(f'{database_url}/token/latest') response.raise_for_status() if response.status_code == 204: return False elif response.status_code == 200: resp_json = response.json() return resp_json['token']['expiration_seconds'] + resp_json['token']['timestamp'] > datetime.now().timestamp() return False def save_tokens(access_token, refresh_token, expiration_seconds): response = requests.post( f'{database_url}/token', headers={ 'Content-Type': 'application/json' }, json={ 'access_token': access_token, 'refresh_token': refresh_token, 'expiration_seconds': expiration_seconds } ) response.raise_for_status() if __name__ == '__main__': app.run(host='0.0.0.0', debug=True, port=5000)