(20250104) Breeze authorization will be accepted now.
This commit is contained in:
@@ -61,9 +61,6 @@ from utils_v2.api.async_quart import (
|
||||
handle_failed_request
|
||||
)
|
||||
|
||||
# GMail-related utils:
|
||||
from utils_v2.goog.controllers.gmail.gmail_client import SCOPES_GMAIL_MAIL_MANAGEMENT
|
||||
|
||||
# Data Models:
|
||||
from models.core.auth_token import CoreAuthTokenModel
|
||||
|
||||
@@ -124,17 +121,19 @@ async def handle_auth_exception():
|
||||
return await render_template(
|
||||
"/finstitutions/trading/oauth/oauth_failure_v2.html",
|
||||
client = g.client_label,
|
||||
failure_hint = (
|
||||
f"Something went wrong (E). "
|
||||
failure_hint = " ".join([
|
||||
f"Something went wrong (E).",
|
||||
g.client_response.message,
|
||||
f"Please use log-id <b>'{g.log_id}'</b> to check with the support team."
|
||||
)
|
||||
])
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@trading_oauth_callback_bp.route("/callback/<trading_client>", methods = ["POST", "GET"])
|
||||
@trading_oauth_callback_bp.route("/callback/<trading_client>", methods = ["GET", "POST"])
|
||||
@trading_oauth_callback_bp.route("/callback/<trading_client>/<client_user_id>", methods = ["GET", "POST"])
|
||||
@set_api_version(api_version = "1.0.0")
|
||||
@read_input(sanitize_headers = False, sanitize_data = False)
|
||||
@log_request_to_mongo(
|
||||
@@ -152,6 +151,7 @@ async def handle_auth_exception():
|
||||
@handle_failed_request(cleanup_coro = handle_auth_exception)
|
||||
async def trading_oauth_callback(
|
||||
trading_client: str = None,
|
||||
client_user_id: str = None,
|
||||
inbound_headers: dict = None,
|
||||
inbound_data: dict = None,
|
||||
inbound_files: dict = None,
|
||||
@@ -162,6 +162,7 @@ async def trading_oauth_callback(
|
||||
This endpoint gets triggered by the stockbroker's servers to let you know when a user accepted or rejected an
|
||||
authorization request.
|
||||
:param trading_client: The name of the stockbroker that you have received the callback from.
|
||||
:param client_user_id: How the trading client identifies this user.
|
||||
:param inbound_headers: auto-extracted by the decorators.
|
||||
:param inbound_data: auto-extracted by the decorators.
|
||||
:param inbound_files: auto-extracted by the decorators.
|
||||
@@ -174,20 +175,31 @@ async def trading_oauth_callback(
|
||||
|
||||
# Store needed values in 'g':
|
||||
g.log_id = kwargs.get("log_id")
|
||||
g.client_label = "Zerodha (Kite)"
|
||||
g.client_label_map = {
|
||||
"zerodhaKite": "Zerodha (Kite)",
|
||||
"iciciBreeze": "ICICI (Breeze)"
|
||||
}
|
||||
|
||||
# Start by assuming failure:
|
||||
success = None
|
||||
g.client_response = None
|
||||
|
||||
# ┏┓ ┏┓ ┓┓ ┓┏┓•
|
||||
# ┣ ┏┓┏┓ ┏┛┏┓┏┓┏┓┏┫┣┓┏┓ ┃┫ ┓╋┏┓
|
||||
# ┻ ┗┛┛ ┗┛┗ ┛ ┗┛┗┻┛┗┗┻ ┛┗┛┗┗┗
|
||||
# ┳┓ ┓ ┏┓ ┓ •
|
||||
# ┣┫┏┓┏┓┃┏┏┓┏┓ ┗┓┏┓┃┏┓┏╋┓┏┓┏┓
|
||||
# ┻┛┛ ┗┛┛┗┗ ┛ ┗┛┗ ┗┗ ┗┗┗┗┛┛┗
|
||||
|
||||
if trading_client == "zerodha":
|
||||
success = await current_app.zerodha_kite_controller.handle_authorization_callback(
|
||||
g.client_label = g.client_label_map.get(trading_client, trading_client)
|
||||
|
||||
match trading_client:
|
||||
case "zerodhaKite": client_controller = current_app.zerodha_kite_controller
|
||||
case "iciciBreeze": client_controller = current_app.icici_breeze_controller
|
||||
case _: client_controller = None
|
||||
|
||||
if client_controller is not None:
|
||||
g.client_response = await client_controller.handle_authorization_callback(
|
||||
sql_conn = current_app.sql_writer,
|
||||
mongo_data_conn = current_app.data_mongo,
|
||||
inbound_data = inbound_data
|
||||
inbound_data = inbound_data,
|
||||
client_user_id = client_user_id
|
||||
)
|
||||
|
||||
# ┳┓
|
||||
@@ -195,30 +207,35 @@ async def trading_oauth_callback(
|
||||
# ┛┗┗ ┛┣┛┗┛┛┗┛┗
|
||||
# ┛
|
||||
|
||||
# Prepare a set of warning messages:
|
||||
callback_url_upgrade_warning = (
|
||||
"<br><br><b>WARNING: You are using the old callback system which could be discontinued at any time. "
|
||||
"Please update the callback URL on your broker's portal to include your user id in it.</b>"
|
||||
)
|
||||
|
||||
# No valid client:
|
||||
if success is None: return await render_template(
|
||||
if client_controller is None: return await render_template(
|
||||
"/finstitutions/trading/oauth/oauth_failure_v2.html",
|
||||
client = g.client_label,
|
||||
failure_hint = (
|
||||
f"Invalid client '{g.client_label}' selected. "
|
||||
f"Please use log-id '{g.log_id}' to check with the support team."
|
||||
)
|
||||
failure_hint = " ".join([
|
||||
f"Invalid client '{g.client_label}' selected.",
|
||||
f"Please use log-id <b>'{g.log_id}'</b> to check with the support team."
|
||||
])
|
||||
)
|
||||
|
||||
# Successful auth:
|
||||
if success: return await render_template(
|
||||
if g.client_response.success: return await render_template(
|
||||
"/finstitutions/trading/oauth/oauth_success_v2.html",
|
||||
client = g.client_label
|
||||
client = g.client_label,
|
||||
extra_message = callback_url_upgrade_warning if client_user_id is None else ""
|
||||
)
|
||||
|
||||
# Failed auth:
|
||||
if success is None: return await render_template(
|
||||
if g.client_response.success is False: return await render_template(
|
||||
"/finstitutions/trading/oauth/oauth_failure_v2.html",
|
||||
client = g.client_label,
|
||||
failure_hint = (
|
||||
f"Something went wrong (NE). "
|
||||
f"Please use log-id '{g.log_id}' to check with the support team."
|
||||
)
|
||||
failure_hint = " ".join([
|
||||
g.client_response.message,
|
||||
f"Please use log-id <b>'{g.log_id}'</b> to check with the support team."
|
||||
])
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -171,6 +171,9 @@ async def request_oauth_authorization_url(
|
||||
# ┻ ┗┛┛ ┣┛┗┻┣┛┗ ┛ ┻ ┛ ┗┻┗┻┗┛┗┗┫
|
||||
# ┛ ┛
|
||||
|
||||
# This is an internal paper-trading account.
|
||||
# It won't need daily logins for usage.
|
||||
|
||||
if inbound_data.client == "paperTrading":
|
||||
|
||||
# Immediately save the details against that token id:
|
||||
@@ -187,7 +190,7 @@ async def request_oauth_authorization_url(
|
||||
},
|
||||
auth = inbound_data.auth.model_dump(),
|
||||
status = "active",
|
||||
syncFreq = 1500
|
||||
syncFreq = None
|
||||
),
|
||||
token_notes = {
|
||||
"username": inbound_data.auth.username
|
||||
@@ -205,7 +208,7 @@ async def request_oauth_authorization_url(
|
||||
# ┻ ┗┛┛ ┗┛┗ ┛ ┗┛┗┻┛┗┗┻ ┛┗┛┗┗┗
|
||||
|
||||
# PLANNED FLOW FOR ZERODHA-KITE:
|
||||
# Step 01.: (One time) The user will go to the integrations page and add his API Key and SPI Secret there. We store
|
||||
# Step 01.: (One time) The user will go to the integrations page and add his API Key and API Secret there. We store
|
||||
# these values without verification.
|
||||
# Step 02.: (Daily) The user will go to the investments tab and click on his Zerodha account, which will give him
|
||||
# a URL that will take him to Zerodha's official site to log in. When he logs in, Zerodha will hit our
|
||||
@@ -226,17 +229,19 @@ async def request_oauth_authorization_url(
|
||||
authType = "oauth",
|
||||
user = kwargs["session_info"],
|
||||
clientUserId = {
|
||||
"userId": inbound_data.auth.userId,
|
||||
"apiKey": inbound_data.auth.apiKey
|
||||
},
|
||||
auth = inbound_data.auth.model_dump(),
|
||||
status = "active",
|
||||
syncFreq = 1500
|
||||
syncFreq = None
|
||||
),
|
||||
token_notes = {
|
||||
"userId": inbound_data.auth.userId,
|
||||
"apiKey": inbound_data.auth.apiKey,
|
||||
"authUrl": auth_url
|
||||
},
|
||||
display_name = None,
|
||||
display_name = inbound_data.auth.userId,
|
||||
display_picture = None,
|
||||
session_token = inbound_headers["X-Session-Token"]
|
||||
)
|
||||
@@ -248,6 +253,13 @@ async def request_oauth_authorization_url(
|
||||
# ┣ ┏┓┏┓ ┃┃ ┃┃ ┃ ┣┫┏┓┏┓┏┓┓┏┓
|
||||
# ┻ ┗┛┛ ┻┗┛┻┗┛┻ ┻┛┛ ┗ ┗ ┗┗
|
||||
|
||||
# PLANNED FLOW FOR ICICI-BREEZE:
|
||||
# Step 01.: (One time) The user will go to the integrations page and add his Client User ID, API Key, and API Secret
|
||||
# there. We store these values without verification.
|
||||
# Step 02.: (Daily) The user will go to the investments tab and click on his Breeze account, which will give him a
|
||||
# URL that will take him to ICICI's official site to log in. When he logs in, ICICI will hit our callback
|
||||
# URL and give us the authentication details.
|
||||
|
||||
if inbound_data.client == "iciciBreeze":
|
||||
|
||||
# Prepare the inputs:
|
||||
@@ -263,17 +275,19 @@ async def request_oauth_authorization_url(
|
||||
authType = "oauth",
|
||||
user = kwargs["session_info"],
|
||||
clientUserId = {
|
||||
"userId": inbound_data.auth.userId,
|
||||
"apiKey": inbound_data.auth.apiKey
|
||||
},
|
||||
auth = inbound_data.auth.model_dump(),
|
||||
status = "active",
|
||||
syncFreq = 1500
|
||||
syncFreq = None
|
||||
),
|
||||
token_notes = {
|
||||
"userId": inbound_data.auth.userId,
|
||||
"apiKey": inbound_data.auth.apiKey,
|
||||
"authUrl": auth_url
|
||||
},
|
||||
display_name = None,
|
||||
display_name = inbound_data.auth.userId,
|
||||
display_picture = None,
|
||||
session_token = inbound_headers["X-Session-Token"]
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user