72 lines
2.1 KiB
Python
72 lines
2.1 KiB
Python
import json
|
|
import os
|
|
from dataclasses import asdict, dataclass
|
|
from pathlib import Path
|
|
|
|
import requests
|
|
|
|
session_file_path = Path(os.path.join(Path(__file__).parent.parent.parent, "session.json"))
|
|
|
|
|
|
@dataclass
|
|
class SessionMetadata:
|
|
user_id: str
|
|
sid: str
|
|
full_name: str
|
|
|
|
def save(self):
|
|
"""Save session info on base fold"""
|
|
session_path = session_file_path
|
|
with open(session_path, "w") as session_file:
|
|
json.dump(asdict(self), session_file, indent=4)
|
|
|
|
|
|
class OtpLogin:
|
|
def __init__(self, email: str):
|
|
self.email = email
|
|
self.opt_url = "https://frappecloud.com/api/method/press.api.account.send_otp"
|
|
self.login_url = "https://frappecloud.com/api/method/press.api.account.verify_otp_and_login"
|
|
self.me = "https://frappecloud.com/api/method/press.api.account.get"
|
|
|
|
def send_otp(self):
|
|
"""Send otp to the email address"""
|
|
response = requests.post(self.opt_url, data={"email": self.email})
|
|
response.raise_for_status()
|
|
|
|
def _parse_session_info(self, cookie_data: str, response_data: dict[str, str]) -> SessionMetadata:
|
|
cookies = cookie_data.split(";")
|
|
cookies = [data.strip() for data in cookies]
|
|
|
|
for cookie in cookies:
|
|
if "sid" in cookie:
|
|
sid = cookie.replace("sid=", "")
|
|
break
|
|
|
|
return SessionMetadata(user_id=self.email, full_name=response_data.get("full_name"), sid=sid)
|
|
|
|
def verify_otp_and_get_session_metadata(self, otp) -> SessionMetadata:
|
|
"""Verify otp for user and get session id"""
|
|
login_response = requests.post(self.login_url, data={"email": self.email, "otp": otp})
|
|
login_response.raise_for_status()
|
|
|
|
return self._parse_session_info(
|
|
cookie_data=login_response.headers.get("Set-Cookie"), response_data=login_response.json()
|
|
)
|
|
|
|
def _check_sid(self, sid: str) -> bool:
|
|
response = requests.get(self.me, cookies={"sid": sid})
|
|
return response.ok
|
|
|
|
def verify_existing_session(self) -> bool:
|
|
"""Verify existing session"""
|
|
if not os.path.exists(session_file_path):
|
|
return False
|
|
|
|
try:
|
|
with open(session_file_path, "r") as session_file:
|
|
session_data = json.loads(session_file.read())
|
|
sid = session_data.get("sid")
|
|
return self._check_sid(sid)
|
|
except json.decoder.JSONDecodeError:
|
|
return False
|