(20241221) Zerodha Auth Ready. Users can now integrate Kite.
This commit is contained in:
@@ -59,18 +59,15 @@ from utils_v2.api.async_quart import (
|
||||
handle_cancelled_request
|
||||
)
|
||||
|
||||
# GMail-related utils:
|
||||
from utils_v2.goog.controllers.gmail.gmail_client import SCOPES_GMAIL_MAIL_MANAGEMENT
|
||||
|
||||
# Common:
|
||||
from shared import constants
|
||||
|
||||
# Data Models:
|
||||
from models.api.mail.oauth import (
|
||||
OAuthMailAuthorizationRequestHeaders,
|
||||
OAuthMailAuthorizationRequestData
|
||||
)
|
||||
from models.core.auth_token import CoreAuthTokenModel
|
||||
from models.api.finstitutions.trading.auth import (
|
||||
TradingAuthRequestHeaders,
|
||||
TradingAuthRequestData
|
||||
)
|
||||
|
||||
# For asynchronous activities:
|
||||
import asyncio
|
||||
@@ -131,13 +128,13 @@ def init(blueprint_setup_state):
|
||||
@log_chain_to_mongo(attr_name = "logs_mongo")
|
||||
@should_not_be_under_maintenance(attr_name = "is_under_maintenance")
|
||||
@validate_input(
|
||||
header_validator = lambda x: OAuthMailAuthorizationRequestHeaders(**x).model_dump(),
|
||||
data_validator = lambda x: OAuthMailAuthorizationRequestData(**x)
|
||||
header_validator = lambda x: TradingAuthRequestHeaders(**x).model_dump(),
|
||||
data_validator = lambda x: TradingAuthRequestData(**x)
|
||||
)
|
||||
@handle_cancelled_request()
|
||||
async def request_oauth_authorization_url(
|
||||
inbound_headers: dict | OAuthMailAuthorizationRequestHeaders = None,
|
||||
inbound_data: dict | OAuthMailAuthorizationRequestData = None,
|
||||
inbound_headers: dict | TradingAuthRequestHeaders = None,
|
||||
inbound_data: dict | TradingAuthRequestData = None,
|
||||
inbound_files: dict = None,
|
||||
**kwargs
|
||||
):
|
||||
@@ -168,48 +165,47 @@ async def request_oauth_authorization_url(
|
||||
# Start by assuming failure:
|
||||
auth_url = None
|
||||
|
||||
# ┏┓ ┏┳┓ ┓ ┓┏┓
|
||||
# ┃┓┏┓┏┓┏┓┏┓┏┓╋┏┓ ┃ ┏┓┃┏┏┓┏┓ ┃┫ ┏┓┓┏
|
||||
# ┗┛┗ ┛┗┗ ┛ ┗┻┗┗ ┻ ┗┛┛┗┗ ┛┗ ┛┗┛┗ ┗┫
|
||||
# ┛
|
||||
# ┏┓ ┏┓ ┓┓ ┓┏┓•
|
||||
# ┣ ┏┓┏┓ ┏┛┏┓┏┓┏┓┏┫┣┓┏┓ ┃┫ ┓╋┏┓
|
||||
# ┻ ┗┛┛ ┗┛┗ ┛ ┗┛┗┻┛┗┗┻ ┛┗┛┗┗┗
|
||||
|
||||
# Make a user identifier from the session info:
|
||||
token_key = await current_app.mail_controller.generate_token_key(
|
||||
db_conn = current_app.sql_writer,
|
||||
mongo_conn = current_app.data_mongo,
|
||||
auth_token = CoreAuthTokenModel(
|
||||
serviceType = "email",
|
||||
client = inbound_data.mailClient,
|
||||
authType = "oauth",
|
||||
user = kwargs["session_info"],
|
||||
clientUserId = {"email": inbound_data.mailId},
|
||||
status = "pending",
|
||||
syncFreq = inbound_data.syncFreq,
|
||||
),
|
||||
session_token = inbound_headers["X-Session-Token"]
|
||||
)
|
||||
if token_key is None:
|
||||
return ResponseModel(
|
||||
status_code = StatusCodes.FAILED,
|
||||
http_code = HttpCodes.INTERNAL_SERVER_ERROR,
|
||||
message = "Failed to generate token key."
|
||||
# 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
|
||||
# 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
|
||||
# callback URL and give us the authentication details.
|
||||
|
||||
if inbound_data.client == "zerodhaKite":
|
||||
|
||||
# Prepare the inputs:
|
||||
auth_url = await current_app.zerodha_kite_controller.get_authorization_url(api_key = inbound_data.auth.apiKey)
|
||||
|
||||
# Immediately save the details against that token id:
|
||||
success = await current_app.zerodha_kite_controller.set_token_direct(
|
||||
sql_conn = current_app.sql_writer,
|
||||
mongo_data_conn = current_app.data_mongo,
|
||||
auth_token = CoreAuthTokenModel(
|
||||
serviceType = "stockTrading",
|
||||
client = inbound_data.client,
|
||||
authType = "oauth",
|
||||
user = kwargs["session_info"],
|
||||
clientUserId = {
|
||||
"apiKey": inbound_data.auth.apiKey
|
||||
},
|
||||
auth = inbound_data.auth.model_dump(),
|
||||
status = "active",
|
||||
syncFreq = 1500
|
||||
),
|
||||
token_notes = {
|
||||
"apiKey": inbound_data.auth.apiKey,
|
||||
"authUrl": auth_url
|
||||
},
|
||||
session_token = inbound_headers["X-Session-Token"]
|
||||
)
|
||||
|
||||
# ┏┓ ┏┓┳┳┓ •┓
|
||||
# ┣ ┏┓┏┓ ┃┓┃┃┃┏┓┓┃
|
||||
# ┻ ┗┛┛ ┗┛┛ ┗┗┻┗┗
|
||||
|
||||
if inbound_data.mailClient == "gmail":
|
||||
|
||||
# Get the authorization URL:
|
||||
auth_url = await current_app.gmail_client.get_authorization_url(
|
||||
scopes = SCOPES_GMAIL_MAIL_MANAGEMENT,
|
||||
state = str(token_key),
|
||||
access_type = "offline",
|
||||
approval_prompt = "force",
|
||||
include_granted_scopes = "true",
|
||||
user_email = inbound_data.mailId
|
||||
)
|
||||
# Check if things were successful:
|
||||
if not success: auth_url = None
|
||||
|
||||
# ┳┓
|
||||
# ┣┫┏┓┏┏┓┏┓┏┓┏┏┓
|
||||
@@ -221,7 +217,7 @@ async def request_oauth_authorization_url(
|
||||
status_code = StatusCodes.OK if auth_url else StatusCodes.FAILED,
|
||||
http_code = HttpCodes.SUCCESS if auth_url else HttpCodes.INTERNAL_SERVER_ERROR,
|
||||
data = {
|
||||
"client": inbound_data.mailClient,
|
||||
"client": inbound_data.client,
|
||||
"authorizationUrl": auth_url
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user