235 lines
6.6 KiB
Python
235 lines
6.6 KiB
Python
from typing import Dict, List
|
|
|
|
import jingrow
|
|
from jingrow.utils import get_url
|
|
|
|
from press.api.developer import raise_invalid_key_error
|
|
from press.api.site import get_plans as get_site_plans
|
|
from press.utils.telemetry import capture
|
|
|
|
|
|
class DeveloperApiHandler:
|
|
def __init__(self, secret_key: str) -> None:
|
|
self.secret_key = secret_key
|
|
self.validate_secret_key()
|
|
|
|
def validate_secret_key(self):
|
|
"""Validate secret_key and set app subscription name and pg"""
|
|
|
|
if not self.secret_key or not isinstance(self.secret_key, str):
|
|
raise_invalid_key_error()
|
|
|
|
app_subscription_name = jingrow.db.exists(
|
|
"Subscription", {"secret_key": self.secret_key, "enabled": 1}
|
|
)
|
|
|
|
if not app_subscription_name:
|
|
raise_invalid_key_error()
|
|
|
|
self.app_subscription_name = app_subscription_name
|
|
self.set_subscription_pg()
|
|
|
|
def set_subscription_pg(self):
|
|
"""To be called after `secret_key` validation"""
|
|
self.app_subscription_pg = jingrow.get_pg("Subscription", self.app_subscription_name)
|
|
|
|
def get_subscription_status(self) -> str:
|
|
return self.app_subscription_pg.status
|
|
|
|
def get_subscription_info(self) -> Dict:
|
|
"""Important rule for security: Send info back carefully"""
|
|
app_subscription_dict = self.app_subscription_pg.as_dict()
|
|
fields_to_send = [
|
|
"document_name",
|
|
"enabled",
|
|
"plan",
|
|
"site",
|
|
]
|
|
|
|
filtered_dict = {
|
|
x: app_subscription_dict[x] for x in app_subscription_dict if x in fields_to_send
|
|
}
|
|
|
|
return filtered_dict
|
|
|
|
def get_subscription(self) -> Dict:
|
|
team = self.app_subscription_pg.team
|
|
with SessionManager(team) as _:
|
|
currency, address = jingrow.db.get_value(
|
|
"Team", team, ["currency", "billing_address"]
|
|
)
|
|
team_pg = jingrow.get_pg("Team", team)
|
|
response = {
|
|
"currency": currency,
|
|
"address": jingrow.db.get_value(
|
|
"Address",
|
|
address,
|
|
["address_line1", "city", "state", "country", "pincode"],
|
|
as_dict=True,
|
|
)
|
|
if address
|
|
else {},
|
|
"team": self.app_subscription_pg.team,
|
|
"countries": jingrow.db.get_all("Country", pluck="name"),
|
|
"plans": get_site_plans(),
|
|
"has_billing_info": (
|
|
team_pg.default_payment_method
|
|
or team_pg.get_balance() > 0
|
|
or team_pg.free_account
|
|
),
|
|
"current_plan": jingrow.db.get_value("Site", self.app_subscription_pg.site, "plan"),
|
|
}
|
|
|
|
capture("attempted", "fc_subscribe", team)
|
|
return response
|
|
|
|
def update_billing_info(self, data: Dict) -> str:
|
|
team = self.app_subscription_pg.team
|
|
with SessionManager(team) as _:
|
|
team_pg = jingrow.get_pg("Team", team)
|
|
team_pg.update_billing_details(data)
|
|
|
|
capture("updated_address", "fc_subscribe", team)
|
|
return "success"
|
|
|
|
def get_publishable_key_and_setup_intent(self):
|
|
with SessionManager(self.app_subscription_pg.team) as _:
|
|
from press.api.billing import get_publishable_key_and_setup_intent
|
|
|
|
return get_publishable_key_and_setup_intent()
|
|
|
|
def setup_intent_success(self, setup_intent):
|
|
team = self.app_subscription_pg.team
|
|
with SessionManager(team) as _:
|
|
from press.api.billing import setup_intent_success
|
|
|
|
capture("added_card", "fc_subscribe", team)
|
|
return setup_intent_success(setup_intent)
|
|
|
|
def change_site_plan(self, plan):
|
|
team = self.app_subscription_pg.team
|
|
with SessionManager(team) as _:
|
|
site = jingrow.get_pg("Site", self.app_subscription_pg.site)
|
|
site.change_plan(plan)
|
|
capture("changed_plan", "fc_subscribe", team)
|
|
|
|
def send_login_link(self):
|
|
try:
|
|
login_url = self.get_login_url()
|
|
users = jingrow.get_pg("Team", self.app_subscription_pg.team).user
|
|
jingrow.sendmail(
|
|
subject="Login Verification Email",
|
|
recipients=[users],
|
|
template="remote_login",
|
|
args={"login_url": login_url, "site": self.app_subscription_pg.site},
|
|
now=True,
|
|
)
|
|
return "success"
|
|
except Exception as e:
|
|
return e
|
|
|
|
def get_login_url(self):
|
|
# check for active tokens
|
|
team = self.app_subscription_pg.team
|
|
if jingrow.db.exists(
|
|
"Saas Remote Login",
|
|
{
|
|
"team": team,
|
|
"status": "Attempted",
|
|
"expires_on": (">", jingrow.utils.now()),
|
|
},
|
|
):
|
|
pg = jingrow.get_pg(
|
|
"Saas Remote Login",
|
|
{
|
|
"team": team,
|
|
"status": "Attempted",
|
|
"expires_on": (">", jingrow.utils.now()),
|
|
},
|
|
)
|
|
token = pg.token
|
|
else:
|
|
token = jingrow.generate_hash("Saas Remote Login", 50)
|
|
jingrow.get_pg(
|
|
{
|
|
"doctype": "Saas Remote Login",
|
|
"team": team,
|
|
"token": token,
|
|
}
|
|
).insert(ignore_permissions=True)
|
|
jingrow.db.commit()
|
|
|
|
return get_url(
|
|
f"/api/method/press.api.marketplace.login_via_token?token={token}&team={team}&site={self.app_subscription_pg.site}"
|
|
)
|
|
|
|
|
|
class SessionManager:
|
|
# set user for authenticated requests and then switch to guest once completed
|
|
def __init__(self, team: str):
|
|
jingrow.set_user(jingrow.db.get_value("Team", team, "user"))
|
|
|
|
def __enter__(self):
|
|
return self
|
|
|
|
def __exit__(self, exc_type, exc_value, exc_traceback):
|
|
jingrow.set_user("Guest")
|
|
|
|
|
|
# ------------------------------------------------------------
|
|
# API ENDPOINTS
|
|
# ------------------------------------------------------------
|
|
@jingrow.whitelist(allow_guest=True)
|
|
def get_subscription_status(secret_key: str) -> str:
|
|
api_handler = DeveloperApiHandler(secret_key)
|
|
return api_handler.get_subscription_status()
|
|
|
|
|
|
@jingrow.whitelist(allow_guest=True)
|
|
def get_subscription_info(secret_key: str) -> Dict:
|
|
api_handler = DeveloperApiHandler(secret_key)
|
|
return api_handler.get_subscription_info()
|
|
|
|
|
|
@jingrow.whitelist(allow_guest=True)
|
|
def get_subscription(secret_key: str) -> str:
|
|
api_handler = DeveloperApiHandler(secret_key)
|
|
return api_handler.get_subscription()
|
|
|
|
|
|
@jingrow.whitelist(allow_guest=True)
|
|
def get_plans(secret_key: str, subscription: str) -> List:
|
|
api_handler = DeveloperApiHandler(secret_key)
|
|
return api_handler.get_plans(subscription)
|
|
|
|
|
|
@jingrow.whitelist(allow_guest=True)
|
|
def update_billing_info(secret_key: str, data) -> str:
|
|
data = jingrow.parse_json(data)
|
|
api_handler = DeveloperApiHandler(secret_key)
|
|
return api_handler.update_billing_info(data)
|
|
|
|
|
|
@jingrow.whitelist(allow_guest=True)
|
|
def get_publishable_key_and_setup_intent(secret_key: str) -> str:
|
|
api_handler = DeveloperApiHandler(secret_key)
|
|
return api_handler.get_publishable_key_and_setup_intent()
|
|
|
|
|
|
@jingrow.whitelist(allow_guest=True)
|
|
def setup_intent_success(secret_key: str, setup_intent) -> str:
|
|
api_handler = DeveloperApiHandler(secret_key)
|
|
return api_handler.setup_intent_success(setup_intent)
|
|
|
|
|
|
@jingrow.whitelist(allow_guest=True)
|
|
def change_site_plan(secret_key: str, plan: str) -> str:
|
|
api_handler = DeveloperApiHandler(secret_key)
|
|
return api_handler.change_site_plan(plan)
|
|
|
|
|
|
@jingrow.whitelist(allow_guest=True)
|
|
def send_login_link(secret_key: str) -> str:
|
|
api_handler = DeveloperApiHandler(secret_key)
|
|
return api_handler.send_login_link()
|