# Copyright (c) 2022, JINGROW # For license information, please see license.txt import json import os import traceback import jingrow JCLOUDE _AUTH_KEY = "jcloude-auth-logs" JCLOUDE _AUTH_MAX_ENTRIES = 1000000 ALLOWED_PATHS = [ "/api/method/create-site-migration", "/api/method/create-version-upgrade", "/api/method/migrate-to-private-bench", "/api/method/find-my-sites", "/api/method/jingrow.core.pagetype.communication.email.mark_email_as_seen", "/api/method/jingrow.realtime.get_user_info", "/api/method/jingrow.realtime.can_subscribe_pg", "/api/method/jingrow.realtime.can_subscribe_pagetype", "/api/method/jingrow.realtime.has_permission", "/api/method/jingrow.www.login.login_via_jingrow", "/api/method/jingrow.integrations.oauth2.authorize", "/api/method/jingrow.integrations.oauth2.approve", "/api/method/jingrow.integrations.oauth2.get_token", "/api/method/jingrow.integrations.oauth2.openid_profile", "/api/method/jingrow.integrations.oauth2_logins.login_via_jingrow", "/api/method/jingrow.website.pagetype.web_page_view.web_page_view.make_view_log", "/api/method/jingrow.desk.form.utils.add_comment", "/api/method/get-user-sites-list-for-new-ticket", "/api/method/ping", "/api/method/login", "/api/method/logout", "/api/method/jcloude.jcloude.pagetype.razorpay_webhook_log.razorpay_webhook_log.razorpay_webhook_handler", "/api/method/jcloude.jcloude.pagetype.razorpay_webhook_log.razorpay_webhook_log.razorpay_authorized_payment_handler", "/api/method/jcloude.jcloude.pagetype.stripe_webhook_log.stripe_webhook_log.stripe_webhook_handler", "/api/method/jcloude.jcloude.pagetype.drip_email.drip_email.unsubscribe", "/api/method/upload_file", "/api/method/jingrow.search.web_search", "/api/method/jingrow.email.queue.unsubscribe", "/api/method/jcloude.utils.telemetry.capture_read_event", "/api/method/validate_plan_change", "/api/method/marketplace-apps", "/api/method/jcloude.www.dashboard.get_context_for_dev", "/api/method/jingrow.website.pagetype.web_form.web_form.accept", "/api/method/jingrow.core.pagetype.user.user.test_password_strength", "/api/method/jingrow.core.pagetype.user.user.update_password", "/api/method/get_central_migration_data", ] ALLOWED_WILDCARD_PATHS = [ "/api/method/jcloude.api.", "/api/method/jcloude.saas.", "/api/method/wiki.", "/api/method/jingrow.integrations.oauth2_logins.", "/api/method/jcloude.www.marketplace.index.", ] DENIED_PATHS = [ # Added from jingrow/wwww/.. "/printview", "/printpreview", ] DENIED_WILDCARD_PATHS = [ "/api/", ] def hook(): # noqa: C901 if jingrow.form_dict.cmd: path = f"/api/method/{jingrow.form_dict.cmd}" else: path = jingrow.request.path user_type = jingrow.get_cached_value("User", jingrow.session.user, "user_type") # Allow unchecked access to System Users if user_type == "System User": return if path in DENIED_PATHS: log(path, user_type) jingrow.throw("Access not allowed for this URL", jingrow.AuthenticationError) for denied in DENIED_WILDCARD_PATHS: if path.startswith(denied): for allowed in ALLOWED_WILDCARD_PATHS: if path.startswith(allowed): return if path in ALLOWED_PATHS: return log(path, user_type) jingrow.throw("Access not allowed for this URL", jingrow.AuthenticationError) return def log(path, user_type): data = { "ip": jingrow.local.request_ip, "timestamp": jingrow.utils.now(), "user_type": user_type, "path": path, "user": jingrow.session.user, "referer": jingrow.request.headers.get("Referer", ""), } if jingrow.cache().llen(JCLOUDE _AUTH_KEY) > JCLOUDE _AUTH_MAX_ENTRIES: jingrow.cache().ltrim(JCLOUDE _AUTH_KEY, 1, -1) serialized = json.dumps(data, sort_keys=True, default=str) jingrow.cache().rpush(JCLOUDE _AUTH_KEY, serialized) def flush(): log_file = os.path.join(jingrow.utils.get_bench_path(), "logs", "jcloude.auth.json.log") try: # Fetch all entries without removing from cache logs = jingrow.cache().lrange(JCLOUDE _AUTH_KEY, 0, -1) if logs: logs = list(map(jingrow.safe_decode, logs)) with open(log_file, "a", os.O_NONBLOCK) as f: f.write("\n".join(logs)) f.write("\n") # Remove fetched entries from cache jingrow.cache().ltrim(JCLOUDE _AUTH_KEY, len(logs) - 1, -1) except Exception: traceback.print_exc()