refactor: use HTTP login API instead of incus exec for admin login
Same approach as Frappe Cloud (press) — POST to site's /api/method/login with credentials, extract sid from response cookies. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
e965780684
commit
2719c2276c
|
|
@ -1107,54 +1107,39 @@ def deploy_container_full(container_name, image="erp", pool_name="default", volu
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_login_url(container_name, target_server=None):
|
def get_login_url(container_name, target_server=None):
|
||||||
"""Generate a one-time login URL for a container site (login as Administrator)."""
|
"""Generate a login URL for a container site (login as Administrator).
|
||||||
|
|
||||||
|
Uses direct HTTP POST to the site's /api/method/login endpoint,
|
||||||
|
same approach as Frappe Cloud (press).
|
||||||
|
"""
|
||||||
_check_admin_permission()
|
_check_admin_permission()
|
||||||
|
|
||||||
if not target_server:
|
if not target_server:
|
||||||
frappe.throw("Server name is required")
|
frappe.throw("Server name is required")
|
||||||
|
|
||||||
# Run Python via bench venv inside the container to create a session
|
|
||||||
# Uses heredoc to avoid escaping issues
|
|
||||||
shell_cmd = """su frappe -c 'cd /home/frappe/frappe-bench && ./env/bin/python << "PYEOF"
|
|
||||||
import frappe
|
|
||||||
frappe.init(site="frontend")
|
|
||||||
frappe.connect()
|
|
||||||
sid = frappe.generate_hash()
|
|
||||||
frappe.db.sql(
|
|
||||||
"INSERT INTO `tabSessions` (`sid`, `user`, `data`, `lastused`, `status`) "
|
|
||||||
"VALUES (%s, %s, %s, NOW(), %s)",
|
|
||||||
(sid, "Administrator", "{}", "Active")
|
|
||||||
)
|
|
||||||
frappe.db.commit()
|
|
||||||
frappe.destroy()
|
|
||||||
print(sid)
|
|
||||||
PYEOF
|
|
||||||
'"""
|
|
||||||
|
|
||||||
result = _exec_in_container(target_server, container_name, shell_cmd, timeout=30)
|
|
||||||
|
|
||||||
output = result.get("output", "").strip()
|
|
||||||
|
|
||||||
if result.get("return_code") != 0:
|
|
||||||
return {
|
|
||||||
"success": False,
|
|
||||||
"error": output or "Failed to generate login token",
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the last non-empty line (sid) — skip any Python warnings/output
|
|
||||||
sid = ""
|
|
||||||
for line in reversed(output.split("\n")):
|
|
||||||
line = line.strip()
|
|
||||||
if line and len(line) >= 20 and line.isalnum():
|
|
||||||
sid = line
|
|
||||||
break
|
|
||||||
|
|
||||||
if not sid:
|
|
||||||
return {"success": False, "error": f"Could not parse sid from output: {output[:200]}"}
|
|
||||||
|
|
||||||
host_domain = frappe.conf.get("host_domain", "host.jeyerp.az")
|
host_domain = frappe.conf.get("host_domain", "host.jeyerp.az")
|
||||||
site_url = f"http://{container_name}.{host_domain}"
|
site_url = f"http://{container_name}.{host_domain}"
|
||||||
|
|
||||||
|
# POST to site's login API with admin credentials (like Frappe Press)
|
||||||
|
try:
|
||||||
|
response = requests.post(
|
||||||
|
f"{site_url}/api/method/login",
|
||||||
|
data={"usr": "Administrator", "pwd": "admin"},
|
||||||
|
timeout=10,
|
||||||
|
)
|
||||||
|
except requests.exceptions.ConnectionError:
|
||||||
|
return {"success": False, "error": f"Cannot connect to {site_url}"}
|
||||||
|
except requests.exceptions.Timeout:
|
||||||
|
return {"success": False, "error": f"Connection to {site_url} timed out"}
|
||||||
|
|
||||||
|
sid = response.cookies.get("sid")
|
||||||
|
|
||||||
|
if not sid or sid == "Guest":
|
||||||
|
return {
|
||||||
|
"success": False,
|
||||||
|
"error": "Login failed. Check that site is running and admin password is correct.",
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"success": True,
|
"success": True,
|
||||||
"url": site_url,
|
"url": site_url,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue