123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
- # MIT License. See license.txt
- from __future__ import unicode_literals
- 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
- from frappe.utils import cint
- @frappe.whitelist()
- def add(doctype, name, user=None, read=1, write=0, share=0, everyone=0, flags=None):
- """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),
- "share": cint(share)
- })
- doc.save(ignore_permissions=True)
- notify_assignment(user, doctype, name, everyone)
- 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.share = 0
- share.save()
- if not (share.read or share.write 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.sql("""select
- `name`, `user`, `read`, `write`, `share`, `everyone`
- from
- `tabDocShare`
- where
- share_doctype=%s and share_name=%s""",
- (doctype, name), as_dict=True)
- 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):
- if not (shared_by and doctype and doc_name) or everyone: return
- from frappe.utils import get_fullname
- title_field = frappe.get_meta(doctype).get_title_field()
- title = doc_name if title_field == "name" else \
- frappe.db.get_value(doctype, doc_name, title_field)
- 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), frappe.bold(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)
|