refactor: don't use impersonate directly, use similar logic
This will allow impersonating as well Signed-off-by: Akhil Narang <me@akhilnarang.dev>
This commit is contained in:
parent
1dc767f671
commit
15065a93e3
5 changed files with 36 additions and 21 deletions
|
|
@ -163,12 +163,12 @@ class LoginManager:
|
||||||
frappe.form_dict.pop("pwd", None)
|
frappe.form_dict.pop("pwd", None)
|
||||||
self.post_login()
|
self.post_login()
|
||||||
|
|
||||||
def post_login(self):
|
def post_login(self, duration: str | None = None, audit_user: str | None = None):
|
||||||
self.run_trigger("on_login")
|
self.run_trigger("on_login")
|
||||||
validate_ip_address(self.user)
|
validate_ip_address(self.user)
|
||||||
self.validate_hour()
|
self.validate_hour()
|
||||||
self.get_user_info()
|
self.get_user_info()
|
||||||
self.make_session()
|
self.make_session(duration=duration, audit_user=audit_user)
|
||||||
self.setup_boot_cache()
|
self.setup_boot_cache()
|
||||||
self.set_user_info()
|
self.set_user_info()
|
||||||
|
|
||||||
|
|
@ -216,13 +216,15 @@ class LoginManager:
|
||||||
def clear_preferred_language(self):
|
def clear_preferred_language(self):
|
||||||
frappe.local.cookie_manager.delete_cookie("preferred_language")
|
frappe.local.cookie_manager.delete_cookie("preferred_language")
|
||||||
|
|
||||||
def make_session(self, resume=False):
|
def make_session(self, resume: bool = False, duration: str | None = None, audit_user: str | None = None):
|
||||||
# start session
|
# start session
|
||||||
frappe.local.session_obj = Session(
|
frappe.local.session_obj = Session(
|
||||||
user=self.user,
|
user=self.user,
|
||||||
resume=resume,
|
resume=resume,
|
||||||
full_name=self.full_name,
|
full_name=self.full_name,
|
||||||
user_type=self.user_type,
|
user_type=self.user_type,
|
||||||
|
duration=duration,
|
||||||
|
audit_user=audit_user,
|
||||||
)
|
)
|
||||||
|
|
||||||
# reset user if changed to Guest
|
# reset user if changed to Guest
|
||||||
|
|
@ -342,13 +344,14 @@ class LoginManager:
|
||||||
"""login as guest"""
|
"""login as guest"""
|
||||||
self.login_as("Guest")
|
self.login_as("Guest")
|
||||||
|
|
||||||
def login_as(self, user):
|
def login_as(self, user: str, duration: str | None = None, audit_user: str | None = None):
|
||||||
self.user = user
|
self.user = user
|
||||||
self.post_login()
|
self.post_login(duration, audit_user)
|
||||||
|
|
||||||
def impersonate(self, user):
|
def impersonate(self, user):
|
||||||
current_user = frappe.session.user
|
current_user = frappe.session.user
|
||||||
self.login_as(user)
|
session_data = frappe.local.session_obj.data.data
|
||||||
|
self.login_as(user, duration=session_data.duration, audit_user=session_data.audit_user)
|
||||||
# Flag this session as impersonated session, so other code can log this.
|
# Flag this session as impersonated session, so other code can log this.
|
||||||
frappe.local.session_obj.set_impersonated(current_user)
|
frappe.local.session_obj.set_impersonated(current_user)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1200,9 +1200,6 @@ def browse(
|
||||||
frappe.init(site)
|
frappe.init(site)
|
||||||
frappe.connect()
|
frappe.connect()
|
||||||
|
|
||||||
frappe.flags.session_duration = duration
|
|
||||||
frappe.flags.audit_user = user_for_audit
|
|
||||||
|
|
||||||
sid = ""
|
sid = ""
|
||||||
if user:
|
if user:
|
||||||
if not frappe.db.exists("User", user):
|
if not frappe.db.exists("User", user):
|
||||||
|
|
@ -1213,7 +1210,7 @@ def browse(
|
||||||
frappe.utils.set_request(path="/")
|
frappe.utils.set_request(path="/")
|
||||||
frappe.local.cookie_manager = CookieManager()
|
frappe.local.cookie_manager = CookieManager()
|
||||||
frappe.local.login_manager = LoginManager()
|
frappe.local.login_manager = LoginManager()
|
||||||
frappe.local.login_manager.login_as(user)
|
frappe.local.login_manager.login_as(user, duration, user_for_audit)
|
||||||
sid = f"/app?sid={frappe.session.sid}"
|
sid = f"/app?sid={frappe.session.sid}"
|
||||||
else:
|
else:
|
||||||
click.echo("Please enable developer mode to login as a user")
|
click.echo("Please enable developer mode to login as a user")
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,9 @@ class Version(Document):
|
||||||
if impersonator := frappe.session.data.get("impersonated_by"):
|
if impersonator := frappe.session.data.get("impersonated_by"):
|
||||||
data["impersonated_by"] = impersonator
|
data["impersonated_by"] = impersonator
|
||||||
|
|
||||||
|
if audit_user := frappe.session.data.get("audit_user"):
|
||||||
|
data["audit_user"] = audit_user
|
||||||
|
|
||||||
def set_diff(self, old: Document, new: Document) -> bool:
|
def set_diff(self, old: Document, new: Document) -> bool:
|
||||||
"""Set the data property with the diff of the docs if present"""
|
"""Set the data property with the diff of the docs if present"""
|
||||||
diff = get_diff(old, new)
|
diff = get_diff(old, new)
|
||||||
|
|
|
||||||
|
|
@ -246,6 +246,12 @@ function get_version_timeline_content(version_doc, frm) {
|
||||||
const impersonated_msg = __("Impersonated by {0}", [get_user_link(impersonated_by)]);
|
const impersonated_msg = __("Impersonated by {0}", [get_user_link(impersonated_by)]);
|
||||||
out = out.map((message) => `${message} · ${impersonated_msg.bold()}`);
|
out = out.map((message) => `${message} · ${impersonated_msg.bold()}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const audit_user = data.audit_user;
|
||||||
|
if (audit_user) {
|
||||||
|
const audit_msg = __("[Action taken by {0}]", [audit_user]);
|
||||||
|
out = out.map((message) => `${message} · ${audit_msg.bold()}`);
|
||||||
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -205,7 +205,15 @@ def generate_csrf_token():
|
||||||
class Session:
|
class Session:
|
||||||
__slots__ = ("_update_in_cache", "data", "full_name", "sid", "time_diff", "user", "user_type")
|
__slots__ = ("_update_in_cache", "data", "full_name", "sid", "time_diff", "user", "user_type")
|
||||||
|
|
||||||
def __init__(self, user, resume=False, full_name=None, user_type=None):
|
def __init__(
|
||||||
|
self,
|
||||||
|
user: str,
|
||||||
|
resume: bool = False,
|
||||||
|
full_name: str | None = None,
|
||||||
|
user_type: str | None = None,
|
||||||
|
duration: str | None = None,
|
||||||
|
audit_user: str | None = None,
|
||||||
|
):
|
||||||
self.sid = cstr(
|
self.sid = cstr(
|
||||||
frappe.form_dict.pop("sid", None) or unquote(frappe.request.cookies.get("sid", "Guest"))
|
frappe.form_dict.pop("sid", None) or unquote(frappe.request.cookies.get("sid", "Guest"))
|
||||||
)
|
)
|
||||||
|
|
@ -225,7 +233,7 @@ class Session:
|
||||||
else:
|
else:
|
||||||
if self.user:
|
if self.user:
|
||||||
self.validate_user()
|
self.validate_user()
|
||||||
self.start()
|
self.start(duration, audit_user)
|
||||||
|
|
||||||
def validate_user(self):
|
def validate_user(self):
|
||||||
if not frappe.get_cached_value("User", self.user, "enabled"):
|
if not frappe.get_cached_value("User", self.user, "enabled"):
|
||||||
|
|
@ -234,7 +242,7 @@ class Session:
|
||||||
frappe.ValidationError,
|
frappe.ValidationError,
|
||||||
)
|
)
|
||||||
|
|
||||||
def start(self):
|
def start(self, duration: str | None = None, audit_user: str | None = None):
|
||||||
"""start a new session"""
|
"""start a new session"""
|
||||||
# generate sid
|
# generate sid
|
||||||
if self.user == "Guest":
|
if self.user == "Guest":
|
||||||
|
|
@ -246,17 +254,17 @@ class Session:
|
||||||
self.sid = self.data.sid = sid
|
self.sid = self.data.sid = sid
|
||||||
self.data.data.user = self.user
|
self.data.data.user = self.user
|
||||||
self.data.data.session_ip = frappe.local.request_ip
|
self.data.data.session_ip = frappe.local.request_ip
|
||||||
if frappe.flags.session_duration:
|
if duration:
|
||||||
self.data.data.fixed_duration = True
|
self.data.data.fixed_duration = True
|
||||||
|
|
||||||
if frappe.flags.audit_user:
|
if audit_user:
|
||||||
self.data.data.impersonated_by = frappe.flags.audit_user
|
self.data.data.audit_user = audit_user
|
||||||
|
|
||||||
if self.user != "Guest":
|
if self.user != "Guest":
|
||||||
self.data.data.update(
|
self.data.data.update(
|
||||||
{
|
{
|
||||||
"last_updated": frappe.utils.now(),
|
"last_updated": frappe.utils.now(),
|
||||||
"session_expiry": frappe.flags.session_duration or get_expiry_period(),
|
"session_expiry": duration or get_expiry_period(),
|
||||||
"full_name": self.full_name,
|
"full_name": self.full_name,
|
||||||
"user_type": self.user_type,
|
"user_type": self.user_type,
|
||||||
}
|
}
|
||||||
|
|
@ -392,9 +400,6 @@ class Session:
|
||||||
if frappe.session.user == "Guest":
|
if frappe.session.user == "Guest":
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.data.data.fixed_duration:
|
|
||||||
return
|
|
||||||
|
|
||||||
now = frappe.utils.now_datetime()
|
now = frappe.utils.now_datetime()
|
||||||
|
|
||||||
# update session in db
|
# update session in db
|
||||||
|
|
@ -406,7 +411,8 @@ class Session:
|
||||||
if (
|
if (
|
||||||
force or (time_diff is None) or (time_diff > 600) or self._update_in_cache
|
force or (time_diff is None) or (time_diff > 600) or self._update_in_cache
|
||||||
) and not frappe.flags.read_only:
|
) and not frappe.flags.read_only:
|
||||||
self.data.data.last_updated = now
|
if not self.data.data.fixed_duration:
|
||||||
|
self.data.data.last_updated = now
|
||||||
self.data.data.lang = str(frappe.lang)
|
self.data.data.lang = str(frappe.lang)
|
||||||
|
|
||||||
Sessions = frappe.qb.DocType("Sessions")
|
Sessions = frappe.qb.DocType("Sessions")
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue