seitime-frappe/frappe/share.py
Gavin D'souza 3446026555 chore: Update header: license.txt => LICENSE
The license.txt file has been replaced with LICENSE for quite a while
now. INAL but it didn't seem accurate to say "hey, checkout license.txt
although there's no such file". Apart from this, there were
inconsistencies in the headers altogether...this change brings
consistency.
2021-09-03 12:02:59 +05:30

170 lines
4.9 KiB
Python

# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: MIT. See LICENSE
import frappe
from frappe import _
from frappe.desk.form.document_follow import follow_document
from frappe.desk.doctype.notification_log.notification_log import enqueue_create_notification,\
get_title, get_title_html
from frappe.utils import cint
@frappe.whitelist()
def add(doctype, name, user=None, read=1, write=0, submit=0, share=0, everyone=0, flags=None, notify=0):
"""Share the given document with a user."""
if not user:
user = frappe.session.user
if not (flags or {}).get("ignore_share_permission"):
check_share_permission(doctype, name)
share_name = get_share_name(doctype, name, user, everyone)
if share_name:
doc = frappe.get_doc("DocShare", share_name)
else:
doc = frappe.new_doc("DocShare")
doc.update({
"user": user,
"share_doctype": doctype,
"share_name": name,
"everyone": cint(everyone)
})
if flags:
doc.flags.update(flags)
doc.update({
# always add read, since you are adding!
"read": 1,
"write": cint(write),
"submit": cint(submit),
"share": cint(share)
})
doc.save(ignore_permissions=True)
notify_assignment(user, doctype, name, everyone, notify=notify)
follow_document(doctype, name, user)
return doc
def remove(doctype, name, user, flags=None):
share_name = frappe.db.get_value("DocShare", {"user": user, "share_name": name,
"share_doctype": doctype})
if share_name:
frappe.delete_doc("DocShare", share_name, flags=flags)
@frappe.whitelist()
def set_permission(doctype, name, user, permission_to, value=1, everyone=0):
"""Set share permission."""
check_share_permission(doctype, name)
share_name = get_share_name(doctype, name, user, everyone)
value = int(value)
if not share_name:
if value:
share = add(doctype, name, user, everyone=everyone, **{permission_to: 1})
else:
# no share found, nothing to remove
share = {}
pass
else:
share = frappe.get_doc("DocShare", share_name)
share.flags.ignore_permissions = True
share.set(permission_to, value)
if not value:
# un-set higher-order permissions too
if permission_to=="read":
share.read = share.write = share.submit = share.share = 0
share.save()
if not (share.read or share.write or share.submit or share.share):
share.delete()
share = {}
return share
@frappe.whitelist()
def get_users(doctype, name):
"""Get list of users with which this document is shared"""
return frappe.db.get_all("DocShare",
fields=["`name`", "`user`", "`read`", "`write`", "`submit`", "`share`", "everyone", "owner", "creation"],
filters=dict(
share_doctype=doctype,
share_name=name
))
def get_shared(doctype, user=None, rights=None):
"""Get list of shared document names for given user and DocType.
:param doctype: DocType of which shared names are queried.
:param user: User for which shared names are queried.
:param rights: List of rights for which the document is shared. List of `read`, `write`, `share`"""
if not user:
user = frappe.session.user
if not rights:
rights = ["read"]
filters = [[right, '=', 1] for right in rights]
filters += [['share_doctype', '=', doctype]]
or_filters = [['user', '=', user]]
if user != 'Guest':
or_filters += [['everyone', '=', 1]]
shared_docs = frappe.db.get_all('DocShare',
fields=['share_name'],
filters=filters,
or_filters=or_filters)
return [doc.share_name for doc in shared_docs]
def get_shared_doctypes(user=None):
"""Return list of doctypes in which documents are shared for the given user."""
if not user:
user = frappe.session.user
return frappe.db.sql_list("select distinct share_doctype from tabDocShare where (user=%s or everyone=1)", user)
def get_share_name(doctype, name, user, everyone):
if cint(everyone):
share_name = frappe.db.get_value("DocShare", {"everyone": 1, "share_name": name,
"share_doctype": doctype})
else:
share_name = frappe.db.get_value("DocShare", {"user": user, "share_name": name,
"share_doctype": doctype})
return share_name
def check_share_permission(doctype, name):
"""Check if the user can share with other users"""
if not frappe.has_permission(doctype, ptype="share", doc=name):
frappe.throw(_("No permission to {0} {1} {2}").format("share", doctype, name), frappe.PermissionError)
def notify_assignment(shared_by, doctype, doc_name, everyone, notify=0):
if not (shared_by and doctype and doc_name) or everyone or not notify:
return
from frappe.utils import get_fullname
title = get_title(doctype, doc_name)
reference_user = get_fullname(frappe.session.user)
notification_message = _('{0} shared a document {1} {2} with you').format(
frappe.bold(reference_user), frappe.bold(doctype), get_title_html(title))
notification_doc = {
'type': 'Share',
'document_type': doctype,
'subject': notification_message,
'document_name': doc_name,
'from_user': frappe.session.user
}
enqueue_create_notification(shared_by, notification_doc)