import json import frappe ALLOWED_PATHS = [ "/api/method/ping", "/api/method/login", "/api/method/logout", "/api/method/frappe.core.doctype.communication.email.mark_email_as_seen", "/api/method/frappe.realtime.get_user_info", "/api/method/frappe.realtime.can_subscribe_doc", "/api/method/frappe.realtime.can_subscribe_doctype", "/api/method/frappe.realtime.has_permission", "/api/method/frappe.integrations.oauth2.authorize", "/api/method/frappe.integrations.oauth2.approve", "/api/method/frappe.integrations.oauth2.get_token", "/api/method/frappe.www.login.login_via_google", "/api/method/frappe.www.login.login_via_github", "/api/method/frappe.www.login.login_via_facebook", "/api/method/frappe.www.login.login_via_frappe", "/api/method/frappe.www.login.login_via_office365", "/api/method/frappe.www.login.login_via_salesforce", "/api/method/frappe.www.login.login_via_fairlogin", "/api/method/frappe.www.login.login_via_keycloak", "/api/method/frappe.www.login.custom", "/api/method/frappe.integrations.oauth2.openid_profile", "/api/method/frappe.website.doctype.web_page_view.web_page_view.make_view_log", "/api/method/upload_file", "/api/method/frappe.search.web_search", "/api/method/frappe.email.queue.unsubscribe", "/api/method/frappe.website.doctype.web_form.web_form.accept", "/api/method/frappe.core.doctype.user.user.test_password_strength", "/api/method/frappe.core.doctype.user.user.update_password", "/api/method/frappe.utils.telemetry.pulse.client.is_enabled", "/api/method/frappe.client.get_value", "/api/method/frappe.client.get_count", "/api/method/frappe.client.get", "/api/method/frappe.client.insert", "/api/method/frappe.client.set_value", "/api/method/frappe.client.delete", "/api/method/frappe.client.get_list", "/api/method/frappe.client.rename_doc", "/api/method/frappe.onboarding.get_onboarding_status", "/api/method/frappe.utils.print_format.download_pdf", "/api/method/frappe.desk.search.search_link", "/api/method/frappe.core.doctype.communication.email.make", "/api/method/frappe.core.doctype.user.user.reset_password", "/api/method/frappe.desk.doctype.notification_log.notification_log.mark_as_read", "/api/method/frappe.desk.doctype.notification_log.notification_log.mark_all_as_read", "/api/method/frappe.sessions.clear", ] def authenticate(): if not frappe.conf.get("block_endpoints"): return if frappe.form_dict.cmd: path = f"/api/method/{frappe.form_dict.cmd}" else: path = frappe.request.path user_type = frappe.db.get_value("User", frappe.session.user, "user_type") if user_type == "System User": return if not path.startswith("/api/"): return if path.startswith("/lms") or path.startswith("/api/method/lms."): return if is_server_script_path(path): return if is_custom_app_endpoint(path): return if path in ALLOWED_PATHS: return frappe.throw(f"Access not allowed for this URL: {path}", frappe.PermissionError) def is_server_script_path(path): endpoint = path.split("/api/method/")[-1] if frappe.db.exists("Server Script", {"script_type": "API", "api_method": endpoint, "disabled": 0}): return True return False def is_custom_app_endpoint(path): allowed_custom_endpoints = frappe.conf.get("allowed_custom_endpoints", []) if isinstance(allowed_custom_endpoints, str): try: parsed = json.loads(allowed_custom_endpoints) allowed_custom_endpoints = parsed if isinstance(parsed, list) else [allowed_custom_endpoints] except Exception: allowed_custom_endpoints = [allowed_custom_endpoints] for endpoint in allowed_custom_endpoints: if endpoint in path: return True return False