Replace config process & improve oauth
* Replaces config.ini with config.json and initiates a workflow to check for presence of config file. If not ask user to create it and stores it in HOME/USER/.config/inopy directory * Improves oauth access token obtention with Flask framework depending on production or development status * Improves also oauth refresh workflow when access token has expiredoriginal/refs/heads/develop
							parent
							
								
									74909f9266
								
							
						
					
					
						commit
						760a12823f
					
				|  | @ -2,8 +2,8 @@ | ||||||
| bearer = f66583f8d6162d3a9bbf276d788b7c6b9f822b82 | bearer = f66583f8d6162d3a9bbf276d788b7c6b9f822b82 | ||||||
| refresh_token = 5d1d5ea774033f4d0aa169f8996401ea4e60d855 | refresh_token = 5d1d5ea774033f4d0aa169f8996401ea4e60d855 | ||||||
| endpoint = https://www.inoreader.com/oauth2/token | endpoint = https://www.inoreader.com/oauth2/token | ||||||
| client_id = 1000003623 | client_id = 1000003644 | ||||||
| client_secret = e9UqU9JGE_hOXfXY3m_coZ5p1OEDfW4E | client_secret = EdUE3HLACUIM2978sq5jY18I0Kj8cIi8 | ||||||
| callback = http://localhost:5000/oauth-callback | callback = http://localhost:5000/oauth-callback | ||||||
| scope = read | scope = read | ||||||
| csrf = 4902358490258 | csrf = 4902358490258 | ||||||
|  | @ -16,4 +16,3 @@ feeds_list_url = https://www.inoreader.com/reader/api/0/subscription/list | ||||||
| summary = Nouveaux articles non lus dans Inoreader | summary = Nouveaux articles non lus dans Inoreader | ||||||
| singular_article = nouvel article dans | singular_article = nouvel article dans | ||||||
| plural_articles = nouveaux articles dans | plural_articles = nouveaux articles dans | ||||||
| 
 |  | ||||||
|  |  | ||||||
|  | @ -0,0 +1,115 @@ | ||||||
|  | import json | ||||||
|  | import os | ||||||
|  | 
 | ||||||
|  | def get_config(config_path, config_file_path): | ||||||
|  | 
 | ||||||
|  |     if os.path.exists(config_path): | ||||||
|  | 
 | ||||||
|  |         if os.path.exists(config_file_path): | ||||||
|  |             pass | ||||||
|  |          | ||||||
|  |         else: | ||||||
|  |             create_file(config_file_path) | ||||||
|  |     else: | ||||||
|  |         os.mkdir(config_path) | ||||||
|  |         print(f'{config_path} created!') | ||||||
|  |         create_file(config_file_path) | ||||||
|  | 
 | ||||||
|  |     # Load the config file | ||||||
|  |     with open(config_file_path) as config_file: | ||||||
|  |         config = json.load(config_file) | ||||||
|  | 
 | ||||||
|  |     bearer = config['oauth']['bearer'] | ||||||
|  |     refresh_token = config['oauth']['refresh_token'] | ||||||
|  |     endpoint = config['oauth']['endpoint'] | ||||||
|  |     client_id = config['oauth']['client_id'] | ||||||
|  |     client_secret = config['oauth']['client_secret'] | ||||||
|  |     callback = config['oauth']['callback'] | ||||||
|  |     scope = config['oauth']['scope'] | ||||||
|  |     csrf = config['oauth']['csrf'] | ||||||
|  |     home_url = config['oauth']['home_url'] | ||||||
|  | 
 | ||||||
|  |     unread_counts_url = config['inoapi']['unread_counts_url'] | ||||||
|  |     feeds_list_url = config['inoapi']['feeds_list_url'] | ||||||
|  | 
 | ||||||
|  |     summary = config['notification']['summary'] | ||||||
|  |     singular_article = config['notification']['singular_article'] | ||||||
|  |     plural_articles = config['notification']['plural_articles'] | ||||||
|  | 
 | ||||||
|  |     prod_status = config['prod']['status'] | ||||||
|  |     browser_path = config['prod']['browser_path'] | ||||||
|  |     host = config['prod']['host'] | ||||||
|  |     port = config['prod']['port'] | ||||||
|  | 
 | ||||||
|  |     variables = locals() | ||||||
|  | 
 | ||||||
|  |     return variables | ||||||
|  | 
 | ||||||
|  | def create_file(config_file_path): | ||||||
|  |     config = {} | ||||||
|  |              | ||||||
|  |     # Ask user for input | ||||||
|  |      | ||||||
|  |     print("\nEnter details about OAuth authentication: \n") | ||||||
|  | 
 | ||||||
|  |     endpoint = input("Enter OAuth endpoint: ") | ||||||
|  |     client_id = input("Enter your client id: ") | ||||||
|  |     client_secret = input("Enter your client secret: ") | ||||||
|  |     callback = input("Enter your callback URL: ") | ||||||
|  |     scope = input("Enter the API scope (e.g. read OR read write): ") | ||||||
|  | 
 | ||||||
|  |     print("\nEnter details about Inoreader API: \n") | ||||||
|  |      | ||||||
|  |     unread_counts_url = input("Enter URL for unread articles: ") | ||||||
|  |     feeds_list_url = input("Enter URL for feeds lists: ") | ||||||
|  | 
 | ||||||
|  |     print("\nEnter details about notification message: \n") | ||||||
|  | 
 | ||||||
|  |     summary = input("Enter summary (title) for notification: ") | ||||||
|  |     singular_article = input("Enter singular label if there is only one unread article (e.g. new article in feed): ") | ||||||
|  |     plural_articles = input("Enter plural label if there are many unread articles (e.g. new articles in feed): ") | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     # Create nested JSON structure | ||||||
|  |     config["oauth"] = { | ||||||
|  |         "bearer": "", | ||||||
|  |         "refresh_token": "", | ||||||
|  |         "endpoint": endpoint, | ||||||
|  |         "client_id": client_id, | ||||||
|  |         "client_secret": client_secret, | ||||||
|  |         "callback": callback, | ||||||
|  |         "scope": scope, | ||||||
|  |         "csrf": "4902358490258", | ||||||
|  |         "home_url": "http://localhost:5000" | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     config["inoapi"] = { | ||||||
|  |        "unread_counts_url": unread_counts_url, | ||||||
|  |        "feeds_list_url": feeds_list_url | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     config["notification"] = { | ||||||
|  |         "summary": summary, | ||||||
|  |         "singular_article": singular_article, | ||||||
|  |         "plural_articles": plural_articles | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     config["prod"] = { | ||||||
|  |         "status": "true", | ||||||
|  |         "browser_path": "/usr/bin/firefox", | ||||||
|  |         "host": "0.0.0.0", | ||||||
|  |         "port": "5000" | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     # Save config to a file | ||||||
|  |     with open(config_file_path, "w") as file: | ||||||
|  |         json.dump(config, file, indent=4) | ||||||
|  | 
 | ||||||
|  |     print(f"{config_file_path} created successfully!") | ||||||
|  | 
 | ||||||
|  | def config(): | ||||||
|  |     config_path = os.path.join(os.environ['HOME'], '.config/inopy') | ||||||
|  |     config_file = 'config.json' | ||||||
|  |     config_file_path = os.path.join(config_path, config_file) | ||||||
|  |     data = get_config(config_path, config_file_path) | ||||||
|  |     return data | ||||||
							
								
								
									
										72
									
								
								ino.py
								
								
								
								
							
							
						
						
									
										72
									
								
								ino.py
								
								
								
								
							|  | @ -30,20 +30,13 @@ | ||||||
| 
 | 
 | ||||||
| import requests | import requests | ||||||
| import json | import json | ||||||
| import configparser |  | ||||||
| import refresh |  | ||||||
| import notif | import notif | ||||||
| import time | import time | ||||||
| import sys | import sys | ||||||
|  | import os | ||||||
|  | from config import config | ||||||
| from test2 import app, run_app | from test2 import app, run_app | ||||||
| 
 | from refresh import refresh | ||||||
| # Configuration parser for reading the config file |  | ||||||
| config = configparser.ConfigParser() |  | ||||||
| config.read('config.ini') |  | ||||||
| 
 |  | ||||||
| # Initiate Summary and message for the notification |  | ||||||
| summary = config.get('Notification', 'summary') |  | ||||||
| message = "" |  | ||||||
| 
 | 
 | ||||||
| """ | """ | ||||||
| 	Read the configuration file. | 	Read the configuration file. | ||||||
|  | @ -56,12 +49,11 @@ message = "" | ||||||
| 	and send a GET request to the API. | 	and send a GET request to the API. | ||||||
| """ | """ | ||||||
| 
 | 
 | ||||||
| def APIrequest(endpoint): | def APIrequest(url, bearer): | ||||||
| 	bearer = config.get('Oauth', 'bearer') |  | ||||||
| 	bearer_string = 'Bearer {}'.format(bearer) | 	bearer_string = 'Bearer {}'.format(bearer) | ||||||
| 	headers = {'Authorization': bearer_string} | 	headers = {'Authorization': bearer_string} | ||||||
| 	url = config.get('InoAPI', endpoint) |  | ||||||
| 	response = requests.get(url, headers=headers) | 	response = requests.get(url, headers=headers) | ||||||
|  | 	print(response.status_code) | ||||||
| 	return response | 	return response | ||||||
| 
 | 
 | ||||||
| # Parse the response as JSON | # Parse the response as JSON | ||||||
|  | @ -75,15 +67,22 @@ def getData(response): | ||||||
| 	in the config | 	in the config | ||||||
| """ | """ | ||||||
| 
 | 
 | ||||||
| def replace(): | message = "" | ||||||
| 	(refreshed_bearer, new_refresh_token) = refresh.refresh() | config = config() | ||||||
| 	config.set('Oauth', 'bearer', refreshed_bearer) | 
 | ||||||
| 	config.set('Oauth', 'refresh_token', new_refresh_token) | bearer = config['bearer'] | ||||||
| 	with open('config.ini', 'w') as config_file: | unread_counts_url = config['unread_counts_url'] | ||||||
| 		config.write(config_file) | feeds_list_url = config['feeds_list_url'] | ||||||
|  | config_path = config['config_file_path'] | ||||||
|  | endpoint = config['endpoint'] | ||||||
|  | client_id = config['client_id'] | ||||||
|  | client_secret = config['client_secret'] | ||||||
|  | refresh_token = config['refresh_token'] | ||||||
|  | summary = config['summary'] | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| # Make a request to get unread counts | # Make a request to get unread counts | ||||||
| unread_response = APIrequest('unread_counts_url') | unread_response = APIrequest(unread_counts_url, bearer) | ||||||
| 
 | 
 | ||||||
| """ | """ | ||||||
| 	If unauthorized (401) status code | 	If unauthorized (401) status code | ||||||
|  | @ -91,14 +90,27 @@ unread_response = APIrequest('unread_counts_url') | ||||||
| 	and make a new request with the updated token. | 	and make a new request with the updated token. | ||||||
| """ | """ | ||||||
| 
 | 
 | ||||||
| if unread_response.status_code == 401: | if unread_response.status_code == 403: | ||||||
| 	replace() | 	print(unread_response.status_code) | ||||||
| 	unread_response = APIrequest('unread_counts_url') |  | ||||||
| 
 |  | ||||||
| elif unread_response.status_code == 403: |  | ||||||
| 	run_app() | 	run_app() | ||||||
| 	config.read('config.ini') | 	#new_config = config() | ||||||
| 	unread_response = APIrequest('unread_counts_url') | 	#bearer = new_config['bearer'] | ||||||
|  | 	with open(config_path) as config_file: | ||||||
|  | 		new_config = json.load(config_file) | ||||||
|  | 	bearer = new_config['oauth']['bearer'] | ||||||
|  | 	print(bearer) | ||||||
|  | 	unread_response = APIrequest(unread_counts_url, bearer) | ||||||
|  | 	print(unread_response.text) | ||||||
|  | 
 | ||||||
|  | elif unread_response.status_code == 401: | ||||||
|  | 	refresh(config_path, endpoint, client_id, client_secret, refresh_token) | ||||||
|  | 	#new_config = config() | ||||||
|  | 	#bearer = new_config['bearer'] | ||||||
|  | 	with open(config_path) as config_file: | ||||||
|  | 		new_config = json.load(config_file) | ||||||
|  | 	bearer = new_config['oauth']['bearer'] | ||||||
|  | 	print(bearer) | ||||||
|  | 	unread_response = APIrequest(unread_counts_url, bearer) | ||||||
| 
 | 
 | ||||||
| elif unread_response.status_code == 200: | elif unread_response.status_code == 200: | ||||||
| 	pass | 	pass | ||||||
|  | @ -109,7 +121,7 @@ elif unread_response.status_code == 200: | ||||||
| 	Parse the unread counts data | 	Parse the unread counts data | ||||||
| """ | """ | ||||||
| 
 | 
 | ||||||
| feeds_list_response = APIrequest('feeds_list_url') | feeds_list_response = APIrequest(feeds_list_url, bearer) | ||||||
| print(feeds_list_response) | print(feeds_list_response) | ||||||
| feeds_list_data = getData(feeds_list_response) | feeds_list_data = getData(feeds_list_response) | ||||||
| unread_data = getData(unread_response) | unread_data = getData(unread_response) | ||||||
|  | @ -155,9 +167,9 @@ for item in unread_data['unreadcounts']: | ||||||
| 		""" | 		""" | ||||||
| 
 | 
 | ||||||
| 		if count == 1: | 		if count == 1: | ||||||
| 			new_articles = config.get('Notification', 'singular_article') | 			new_articles = config['singular_article'] | ||||||
| 		else: | 		else: | ||||||
| 			new_articles = config.get('Notification', 'plural_articles') | 			new_articles = config['plural_articles'] | ||||||
| 		count = str(count) | 		count = str(count) | ||||||
| 		message = message + count + " " + new_articles + " " + ID + "\n" | 		message = message + count + " " + new_articles + " " + ID + "\n" | ||||||
| 	else: | 	else: | ||||||
|  |  | ||||||
|  | @ -0,0 +1,155 @@ | ||||||
|  | from flask import Flask, request, redirect, render_template | ||||||
|  | from config import config | ||||||
|  | from waitress import serve | ||||||
|  | import requests | ||||||
|  | import os | ||||||
|  | import signal | ||||||
|  | import webbrowser | ||||||
|  | import time | ||||||
|  | import json | ||||||
|  | import subprocess | ||||||
|  | import threading | ||||||
|  | 
 | ||||||
|  | config = config() | ||||||
|  | 
 | ||||||
|  | endpoint = config['endpoint'] | ||||||
|  | client_id = config['client_id'] | ||||||
|  | client_secret = config['client_secret'] | ||||||
|  | callback = config['callback'] | ||||||
|  | scope = config['scope'] | ||||||
|  | CSRF = config['csrf'] | ||||||
|  | home_url = config['home_url'] | ||||||
|  | 
 | ||||||
|  | prod_status = config['prod_status'] | ||||||
|  | browser_path = config['browser_path'] | ||||||
|  | host = config['host'] | ||||||
|  | port = config['port'] | ||||||
|  | 
 | ||||||
|  | config_file_path = config['config_file_path'] | ||||||
|  | 
 | ||||||
|  | url = 'https://www.inoreader.com/oauth2/auth?client_id={}&redirect_uri={}&response_type=code&scope={}&state={}'.format(client_id, callback, scope, CSRF) | ||||||
|  | 
 | ||||||
|  | app = Flask(__name__) | ||||||
|  | 
 | ||||||
|  | @app.route('/') | ||||||
|  | def index(): | ||||||
|  |     return redirect(url) | ||||||
|  | 
 | ||||||
|  | @app.route('/oauth-callback') | ||||||
|  | 
 | ||||||
|  | def oauth_callback(): | ||||||
|  |      | ||||||
|  |     # Get the authorization code from the request URL | ||||||
|  |      | ||||||
|  |     authorization_code = request.args.get('code') | ||||||
|  |     csrf_check = request.args.get('state') | ||||||
|  |     error_param = request.args.get('error') | ||||||
|  | 
 | ||||||
|  |     csrf = True if csrf_check == CSRF else False | ||||||
|  |     error = True if error_param != None else False | ||||||
|  | 
 | ||||||
|  |     if csrf == True and error != True: | ||||||
|  | 
 | ||||||
|  |         # Exchange the authorization code for an access token | ||||||
|  |         access_token_url = endpoint | ||||||
|  |         payload = { | ||||||
|  |             'grant_type': 'authorization_code', | ||||||
|  |             'code': authorization_code, | ||||||
|  |             'client_id': client_id, | ||||||
|  |             'client_secret': client_secret, | ||||||
|  |             'redirect_uri': callback | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         response = requests.post(access_token_url, data=payload) | ||||||
|  | 
 | ||||||
|  |         # Parse the response to get the access token | ||||||
|  |         if response.status_code == 200: | ||||||
|  | 
 | ||||||
|  |             access_token = response.json()['access_token'] | ||||||
|  |             refresh_token = response.json()['refresh_token'] | ||||||
|  | 
 | ||||||
|  |             with open(config_file_path, 'r+') as config_file: | ||||||
|  |                 # Load the JSON data from the file | ||||||
|  |                 config = json.load(config_file) | ||||||
|  | 
 | ||||||
|  |                 # Update the token value in the config data | ||||||
|  |                 config['oauth']['bearer'] = access_token | ||||||
|  |                 config['oauth']['refresh_token'] = refresh_token | ||||||
|  | 
 | ||||||
|  |                 # Move the file pointer back to the beginning of the file | ||||||
|  |                 config_file.seek(0) | ||||||
|  | 
 | ||||||
|  |                 # Write the updated config data to the file | ||||||
|  |                 json.dump(config, config_file, indent=4) | ||||||
|  |                 config_file.truncate() | ||||||
|  | 
 | ||||||
|  |         return render_template('success.html', response=(access_token, refresh_token)) | ||||||
|  | 
 | ||||||
|  |     else: | ||||||
|  | 
 | ||||||
|  |         # Redirect the user to a desired URL | ||||||
|  | 
 | ||||||
|  |         if csrf != True: | ||||||
|  |             return render_template('csrf-failed.html', response=(CSRF, csrf_check)) | ||||||
|  | 
 | ||||||
|  |         elif error == True: | ||||||
|  |             error_content = request.args.get('error_description') | ||||||
|  |             return render_template('oauth-error.html', response=(error_param, error_content)) | ||||||
|  | 
 | ||||||
|  |         else: | ||||||
|  |             pass | ||||||
|  | 
 | ||||||
|  | @app.route('/shutdown') | ||||||
|  | def shutdown(): | ||||||
|  |     # Shutting down the Flask app gracefully | ||||||
|  |     #return ('proccess ended', time.sleep(5), os.kill(os.getpid(), signal.SIGINT)) | ||||||
|  |      | ||||||
|  |     request.environ.get('werkzeug.server.shutdown') | ||||||
|  |     return 'Close this browser to terminate the process!' | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | '''def run_prod(): | ||||||
|  | 
 | ||||||
|  |     # Create a new Firefox profile | ||||||
|  |     subprocess.run([browser_path, "-CreateProfile", "new_profile", "-no-remote"]) | ||||||
|  | 
 | ||||||
|  |     # Launch Firefox with the new profile and open the URL | ||||||
|  |     subprocess.run([browser_path, "-P", "new_profile", "-no-remote", home_url]) | ||||||
|  |      | ||||||
|  |     serve(app, host=host, port=port)''' | ||||||
|  | 
 | ||||||
|  | def run_prod(): | ||||||
|  |     # Function to start the Flask server | ||||||
|  |     def start_server(): | ||||||
|  |         serve(app, host=host, port=port) | ||||||
|  | 
 | ||||||
|  |     # Create a new thread for the Flask server | ||||||
|  |     server_thread = threading.Thread(target=start_server) | ||||||
|  | 
 | ||||||
|  |     # Start the Flask server thread | ||||||
|  |     server_thread.start() | ||||||
|  | 
 | ||||||
|  |     # Wait for the Flask server to start (adjust the delay as needed) | ||||||
|  |     time.sleep(2) | ||||||
|  | 
 | ||||||
|  |     # Create a new Firefox profile | ||||||
|  |     subprocess.run([browser_path, "-CreateProfile", "new_profile", "-no-remote"]) | ||||||
|  | 
 | ||||||
|  |     # Launch Firefox with the new profile and open the URL | ||||||
|  |     subprocess.run([browser_path, "-P", "new_profile", "-no-remote", home_url]) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def run_app(): | ||||||
|  | 
 | ||||||
|  |     if prod_status == "true": | ||||||
|  |         print(prod_status) | ||||||
|  |         run_prod() | ||||||
|  |     else: | ||||||
|  |         print(prod_status) | ||||||
|  |         webbrowser.open(home_url) | ||||||
|  |         app.run() | ||||||
|  | 
 | ||||||
|  | if __name__ == '__main__': | ||||||
|  |     #app.run() | ||||||
|  |     run_app() | ||||||
							
								
								
									
										56
									
								
								refresh.py
								
								
								
								
							
							
						
						
									
										56
									
								
								refresh.py
								
								
								
								
							|  | @ -26,33 +26,23 @@ | ||||||
| 
 | 
 | ||||||
| import requests | import requests | ||||||
| import json | import json | ||||||
| import configparser |  | ||||||
| 
 |  | ||||||
| # Initialize a ConfigParser object |  | ||||||
| config = configparser.ConfigParser() |  | ||||||
| 
 |  | ||||||
| # Read the configuration file 'config.ini' |  | ||||||
| config.read('config.ini') |  | ||||||
| 
 |  | ||||||
| # Get the 'endpoint' value from the 'Oauth' section in the configuration file |  | ||||||
| url = config.get('Oauth', 'endpoint') |  | ||||||
| 
 |  | ||||||
| # Prepare the payload for the request |  | ||||||
| payload = { |  | ||||||
| 	"client_id": config.get('Oauth', 'client_id'), |  | ||||||
| 	"client_secret": config.get('Oauth', 'client_secret'), |  | ||||||
| 	"grant_type": "refresh_token", |  | ||||||
| 	"refresh_token": config.get('Oauth', 'refresh_token') |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| # Set the headers for the request |  | ||||||
| headers = {"Content-type": "application/x-www-form-urlencoded"} |  | ||||||
| 
 | 
 | ||||||
| # Define a function named 'refresh' that handles the token refresh logic | # Define a function named 'refresh' that handles the token refresh logic | ||||||
| def refresh(): | def refresh(config_path, endpoint, client_id, client_secret, refresh_token): | ||||||
|  | 
 | ||||||
|  | 	# Set the headers for the request | ||||||
|  | 	headers = {"Content-type": "application/x-www-form-urlencoded"} | ||||||
|  | 
 | ||||||
|  | 	# Prepare the payload for the request | ||||||
|  | 	payload = { | ||||||
|  | 		"client_id": client_id, | ||||||
|  | 		"client_secret": client_secret, | ||||||
|  | 		"grant_type": "refresh_token", | ||||||
|  | 		"refresh_token": refresh_token | ||||||
|  | 	} | ||||||
| 	 | 	 | ||||||
| 	# Send a POST request to the specified URL with the payload and headers | 	# Send a POST request to the specified URL with the payload and headers | ||||||
| 	response = requests.post(url, data=payload, headers=headers) | 	response = requests.post(endpoint, data=payload, headers=headers) | ||||||
| 
 | 
 | ||||||
| 	# Check the response status code | 	# Check the response status code | ||||||
| 	if response.status_code == 200: | 	if response.status_code == 200: | ||||||
|  | @ -67,9 +57,17 @@ def refresh(): | ||||||
| 	refreshed_bearer = data['access_token'] | 	refreshed_bearer = data['access_token'] | ||||||
| 	new_refresh_token = data['refresh_token'] | 	new_refresh_token = data['refresh_token'] | ||||||
| 
 | 
 | ||||||
| 	''' | 	with open(config_path, 'r+') as config_file: | ||||||
| 		Return the refreshed bearer token and the new refresh token  | 		# Load the JSON data from the file | ||||||
| 		in order to use it in the replace() function of the main | 		config = json.load(config_file) | ||||||
| 		ino.py module. | 
 | ||||||
| 	''' | 		# Update the token value in the config data | ||||||
| 	return (refreshed_bearer, new_refresh_token) | 		config['oauth']['bearer'] = refreshed_bearer | ||||||
|  | 		config['oauth']['refresh_token'] = new_refresh_token | ||||||
|  | 
 | ||||||
|  | 		# Move the file pointer back to the beginning of the file | ||||||
|  | 		config_file.seek(0) | ||||||
|  | 
 | ||||||
|  | 		# Write the updated config data to the file | ||||||
|  | 		json.dump(config, config_file, indent=4) | ||||||
|  | 		config_file.truncate() | ||||||
							
								
								
									
										94
									
								
								test2.py
								
								
								
								
							
							
						
						
									
										94
									
								
								test2.py
								
								
								
								
							|  | @ -1,94 +0,0 @@ | ||||||
| from flask import Flask, request, redirect, render_template |  | ||||||
| import requests |  | ||||||
| import os |  | ||||||
| import signal |  | ||||||
| import configparser |  | ||||||
| import webbrowser |  | ||||||
| import time |  | ||||||
| 
 |  | ||||||
| # Configuration parser for reading the config file |  | ||||||
| config = configparser.ConfigParser() |  | ||||||
| config.read('config.ini') |  | ||||||
| 
 |  | ||||||
| endpoint = config.get('Oauth', 'endpoint') |  | ||||||
| client_id = config.get('Oauth', 'client_id') |  | ||||||
| client_secret = config.get('Oauth', 'client_secret') |  | ||||||
| callback = config.get('Oauth', 'callback') |  | ||||||
| scope = config.get('Oauth', 'scope') |  | ||||||
| CSRF = config.get('Oauth', 'CSRF') |  | ||||||
| 
 |  | ||||||
| url = 'https://www.inoreader.com/oauth2/auth?client_id={}&redirect_uri={}&response_type=code&scope={}&state={}'.format(client_id, callback, scope, CSRF) |  | ||||||
| 
 |  | ||||||
| app = Flask(__name__) |  | ||||||
| 
 |  | ||||||
| @app.route('/') |  | ||||||
| def index(): |  | ||||||
|     return redirect(url) |  | ||||||
| 
 |  | ||||||
| @app.route('/oauth-callback') |  | ||||||
| 
 |  | ||||||
| def oauth_callback(): |  | ||||||
|      |  | ||||||
|     # Get the authorization code from the request URL |  | ||||||
|      |  | ||||||
|     authorization_code = request.args.get('code') |  | ||||||
|     csrf_check = request.args.get('state') |  | ||||||
|     error_param = request.args.get('error') |  | ||||||
| 
 |  | ||||||
|     csrf = True if csrf_check == CSRF else False |  | ||||||
|     error = True if error_param != None else False |  | ||||||
| 
 |  | ||||||
|     if csrf == True and error != True: |  | ||||||
| 
 |  | ||||||
|         # Exchange the authorization code for an access token |  | ||||||
|         access_token_url = endpoint |  | ||||||
|         payload = { |  | ||||||
|             'grant_type': 'authorization_code', |  | ||||||
|             'code': authorization_code, |  | ||||||
|             'client_id': client_id, |  | ||||||
|             'client_secret': client_secret, |  | ||||||
|             'redirect_uri': callback |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         response = requests.post(access_token_url, data=payload) |  | ||||||
| 
 |  | ||||||
|         # Parse the response to get the access token |  | ||||||
|         if response.status_code == 200: |  | ||||||
| 
 |  | ||||||
|             access_token = response.json()['access_token'] |  | ||||||
|             refresh_token = response.json()['refresh_token'] |  | ||||||
| 
 |  | ||||||
|             config.set('Oauth', 'bearer', access_token) |  | ||||||
|             config.set('Oauth', 'refresh_token', refresh_token) |  | ||||||
|             with open('config.ini', 'w') as config_file: |  | ||||||
|                 config.write(config_file) |  | ||||||
| 
 |  | ||||||
|         return render_template('success.html', response=(access_token, refresh_token)) |  | ||||||
| 
 |  | ||||||
|     else: |  | ||||||
| 
 |  | ||||||
|         # Redirect the user to a desired URL |  | ||||||
| 
 |  | ||||||
|         if csrf != True: |  | ||||||
|             return render_template('csrf-failed.html', response=(CSRF, csrf_check)) |  | ||||||
| 
 |  | ||||||
|         elif error == True: |  | ||||||
|             error_content = request.args.get('error_description') |  | ||||||
|             return render_template('oauth-error.html', response=(error_param, error_content)) |  | ||||||
| 
 |  | ||||||
|         else: |  | ||||||
|             pass |  | ||||||
| 
 |  | ||||||
| @app.route('/shutdown') |  | ||||||
| def shutdown(): |  | ||||||
|     # Shutting down the Flask app gracefully |  | ||||||
|     return ('proccess ended', time.sleep(5), os.kill(os.getpid(), signal.SIGINT)) |  | ||||||
| 
 |  | ||||||
| def run_app(): |  | ||||||
|     # Open the browser and start the Flask app |  | ||||||
|     webbrowser.open('http://localhost:5000') |  | ||||||
|     app.run() |  | ||||||
| 
 |  | ||||||
| if __name__ == '__main__': |  | ||||||
|     #app.run() |  | ||||||
|     run_app() |  | ||||||
		Loading…
	
		Reference in New Issue