diff --git a/drive/api/permissions.py b/drive/api/permissions.py index a46d88cd8..23414a244 100644 --- a/drive/api/permissions.py +++ b/drive/api/permissions.py @@ -112,14 +112,30 @@ def is_admin(team: str): if frappe.session.user == "Administrator": return True drive_team = {k.user: k for k in frappe.get_doc("Drive Team", team).users} - return drive_team[frappe.session.user].access_level == 2 + member = get_team_member_row(drive_team, frappe.session.user) + return bool(member and member.access_level == 2) def get_access_level(team, user=None): if not user: user = frappe.session.user drive_team = {k.user: k for k in frappe.get_doc("Drive Team", team).users} - return drive_team[user].access_level + member = get_team_member_row(drive_team, user) + if not member: + return 0 + return member.access_level + + +def get_team_member_row(users_by_name: dict, user: str): + """Resolve a team member row; session *user* can differ in case from Link values in the child table.""" + row = users_by_name.get(user) + if row is not None: + return row + key_cf = user.casefold() + for key, row in users_by_name.items(): + if key.casefold() == key_cf: + return row + return None @frappe.whitelist() diff --git a/drive/api/product.py b/drive/api/product.py index 8ee92e0d8..04e1f3e43 100644 --- a/drive/api/product.py +++ b/drive/api/product.py @@ -4,7 +4,7 @@ from frappe.translate import get_all_translations from frappe.utils import escape_html, split_emails, validate_email_address -from drive.api.permissions import get_teams, is_admin +from drive.api.permissions import get_team_member_row, get_teams, is_admin from drive.utils import default_team @@ -60,10 +60,11 @@ def edit_team(team: str, icon: str = None, team_name: str = None): def leave_team(team: str): user = frappe.session.user drive_team = {k.user: k for k in frappe.get_doc("Drive Team", team).users} - if user not in drive_team: + member = get_team_member_row(drive_team, user) + if not member: frappe.throw("User doesn't belong to team") - frappe.delete_doc("Drive Team Member", drive_team[user].name) + frappe.delete_doc("Drive Team Member", member.name) @frappe.whitelist() @@ -300,8 +301,11 @@ def set_user_access(team: str, user: str, access_level: int): if not is_admin(team): frappe.throw("You don't have the permissions for this action.") drive_team = {k.user: k for k in frappe.get_doc("Drive Team", team).users} - drive_team[user].access_level = access_level - drive_team[user].save() + member = get_team_member_row(drive_team, user) + if not member: + frappe.throw("User doesn't belong to team") + member.access_level = access_level + member.save() @frappe.whitelist() @@ -309,9 +313,12 @@ def remove_user(team: str, user_id: str): if not is_admin(team) or user_id == frappe.session.user: frappe.throw("You don't have the permissions for this action.") drive_team = {k.user: k for k in frappe.get_doc("Drive Team", team).users} - if frappe.session.user not in drive_team: + if not get_team_member_row(drive_team, frappe.session.user): + frappe.throw("User doesn't belong to team") + target = get_team_member_row(drive_team, user_id) + if not target: frappe.throw("User doesn't belong to team") - frappe.delete_doc("Drive Team Member", drive_team[user_id].name) + frappe.delete_doc("Drive Team Member", target.name) # SECURITY: send user data with files