Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 
 

342 строки
9.8 KiB

  1. # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
  2. # MIT License. See license.txt
  3. from __future__ import unicode_literals
  4. import frappe, json
  5. from frappe import _dict
  6. import frappe.share
  7. from frappe.utils import cint
  8. from frappe.boot import get_allowed_reports
  9. from frappe.permissions import get_roles, get_valid_perms
  10. from frappe.core.doctype.domain_settings.domain_settings import get_active_modules
  11. class UserPermissions:
  12. """
  13. A user permission object can be accessed as `frappe.get_user()`
  14. """
  15. def __init__(self, name=''):
  16. self.defaults = None
  17. self.name = name or frappe.session.get('user')
  18. self.roles = []
  19. self.all_read = []
  20. self.can_create = []
  21. self.can_read = []
  22. self.can_write = []
  23. self.can_cancel = []
  24. self.can_delete = []
  25. self.can_search = []
  26. self.can_get_report = []
  27. self.can_import = []
  28. self.can_export = []
  29. self.can_print = []
  30. self.can_email = []
  31. self.can_set_user_permissions = []
  32. self.allow_modules = []
  33. self.in_create = []
  34. self.setup_user()
  35. def setup_user(self):
  36. def get_user_doc():
  37. user = None
  38. try:
  39. user = frappe.get_doc("User", self.name).as_dict()
  40. except frappe.DoesNotExistError:
  41. pass
  42. except Exception as e:
  43. # install boo-boo
  44. if not frappe.db.is_table_missing(e): raise
  45. return user
  46. if not frappe.flags.in_install_db and not frappe.flags.in_test:
  47. user_doc = frappe.cache().hget("user_doc", self.name, get_user_doc)
  48. if user_doc:
  49. self.doc = frappe.get_doc(user_doc)
  50. def get_roles(self):
  51. """get list of roles"""
  52. if not self.roles:
  53. self.roles = get_roles(self.name)
  54. return self.roles
  55. def build_doctype_map(self):
  56. """build map of special doctype properties"""
  57. active_domains = frappe.get_active_domains()
  58. self.doctype_map = {}
  59. for r in frappe.db.sql("""select name, in_create, issingle, istable,
  60. read_only, restrict_to_domain, module from tabDocType""", as_dict=1):
  61. if (not r.restrict_to_domain) or (r.restrict_to_domain in active_domains):
  62. self.doctype_map[r['name']] = r
  63. def build_perm_map(self):
  64. """build map of permissions at level 0"""
  65. self.perm_map = {}
  66. for r in get_valid_perms():
  67. dt = r['parent']
  68. if not dt in self.perm_map:
  69. self.perm_map[dt] = {}
  70. for k in frappe.permissions.rights:
  71. if not self.perm_map[dt].get(k):
  72. self.perm_map[dt][k] = r.get(k)
  73. def build_permissions(self):
  74. """build lists of what the user can read / write / create
  75. quirks:
  76. read_only => Not in Search
  77. in_create => Not in create
  78. """
  79. self.build_doctype_map()
  80. self.build_perm_map()
  81. user_shared = frappe.share.get_shared_doctypes()
  82. no_list_view_link = []
  83. active_modules = get_active_modules() or []
  84. for dt in self.doctype_map:
  85. dtp = self.doctype_map[dt]
  86. p = self.perm_map.get(dt, {})
  87. if not p.get("read") and (dt in user_shared):
  88. p["read"] = 1
  89. if not dtp.get('istable'):
  90. if p.get('create') and not dtp.get('issingle'):
  91. if dtp.get('in_create'):
  92. self.in_create.append(dt)
  93. else:
  94. self.can_create.append(dt)
  95. elif p.get('write'):
  96. self.can_write.append(dt)
  97. elif p.get('read'):
  98. if dtp.get('read_only'):
  99. # read_only = "User Cannot Search"
  100. self.all_read.append(dt)
  101. no_list_view_link.append(dt)
  102. else:
  103. self.can_read.append(dt)
  104. if p.get('cancel'):
  105. self.can_cancel.append(dt)
  106. if p.get('delete'):
  107. self.can_delete.append(dt)
  108. if (p.get('read') or p.get('write') or p.get('create')):
  109. if p.get('report'):
  110. self.can_get_report.append(dt)
  111. for key in ("import", "export", "print", "email", "set_user_permissions"):
  112. if p.get(key):
  113. getattr(self, "can_" + key).append(dt)
  114. if not dtp.get('istable'):
  115. if not dtp.get('issingle') and not dtp.get('read_only'):
  116. self.can_search.append(dt)
  117. if dtp.get('module') not in self.allow_modules:
  118. if active_modules and dtp.get('module') not in active_modules:
  119. pass
  120. else:
  121. self.allow_modules.append(dtp.get('module'))
  122. self.can_write += self.can_create
  123. self.can_write += self.in_create
  124. self.can_read += self.can_write
  125. self.shared = frappe.db.sql_list("""select distinct share_doctype from `tabDocShare`
  126. where `user`=%s and `read`=1""", self.name)
  127. self.can_read = list(set(self.can_read + self.shared))
  128. self.all_read += self.can_read
  129. for dt in no_list_view_link:
  130. if dt in self.can_read:
  131. self.can_read.remove(dt)
  132. if "System Manager" in self.get_roles():
  133. docs = [x["name"] for x in frappe.get_all("DocType", "name")]
  134. for docname in docs:
  135. if frappe.get_meta(docname, cached=False).allow_import == 1:
  136. self.can_import.append(docname)
  137. frappe.cache().hset("can_import", frappe.session.user, self.can_import)
  138. def get_defaults(self):
  139. import frappe.defaults
  140. self.defaults = frappe.defaults.get_defaults(self.name)
  141. return self.defaults
  142. def _get(self, key):
  143. if not self.can_read:
  144. self.build_permissions()
  145. return getattr(self, key)
  146. def get_can_read(self):
  147. """return list of doctypes that the user can read"""
  148. if not self.can_read:
  149. self.build_permissions()
  150. return self.can_read
  151. def load_user(self):
  152. d = frappe.db.sql("""select email, first_name, last_name, creation,
  153. email_signature, user_type, language,
  154. mute_sounds, send_me_a_copy, document_follow_notify
  155. from tabUser where name = %s""", (self.name,), as_dict=1)[0]
  156. if not self.can_read:
  157. self.build_permissions()
  158. d.name = self.name
  159. d.roles = self.get_roles()
  160. d.defaults = self.get_defaults()
  161. for key in ("can_create", "can_write", "can_read", "can_cancel", "can_delete",
  162. "can_get_report", "allow_modules", "all_read", "can_search",
  163. "in_create", "can_export", "can_import", "can_print", "can_email",
  164. "can_set_user_permissions"):
  165. d[key] = list(set(getattr(self, key)))
  166. d.all_reports = self.get_all_reports()
  167. return d
  168. def get_all_reports(self):
  169. return get_allowed_reports()
  170. def get_user_fullname(user):
  171. fullname = frappe.db.sql("SELECT CONCAT_WS(' ', first_name, last_name) FROM `tabUser` WHERE name=%s", (user,))
  172. return fullname and fullname[0][0] or ''
  173. def get_fullname_and_avatar(user):
  174. first_name, last_name, avatar, name = frappe.db.get_value("User",
  175. user, ["first_name", "last_name", "user_image", "name"])
  176. return _dict({
  177. "fullname": " ".join(list(filter(None, [first_name, last_name]))),
  178. "avatar": avatar,
  179. "name": name
  180. })
  181. def get_system_managers(only_name=False):
  182. """returns all system manager's user details"""
  183. import email.utils
  184. from frappe.core.doctype.user.user import STANDARD_USERS
  185. system_managers = frappe.db.sql("""SELECT DISTINCT `name`, `creation`,
  186. CONCAT_WS(' ',
  187. CASE WHEN `first_name`= '' THEN NULL ELSE `first_name` END,
  188. CASE WHEN `last_name`= '' THEN NULL ELSE `last_name` END
  189. ) AS fullname
  190. FROM `tabUser` AS p
  191. WHERE `docstatus` < 2
  192. AND `enabled` = 1
  193. AND `name` NOT IN ({})
  194. AND exists
  195. (SELECT *
  196. FROM `tabHas Role` AS ur
  197. WHERE ur.parent = p.name
  198. AND ur.role='System Manager')
  199. ORDER BY `creation` DESC""".format(", ".join(["%s"]*len(STANDARD_USERS))),
  200. STANDARD_USERS, as_dict=True)
  201. if only_name:
  202. return [p.name for p in system_managers]
  203. else:
  204. return [email.utils.formataddr((p.fullname, p.name)) for p in system_managers]
  205. def add_role(user, role):
  206. frappe.get_doc("User", user).add_roles(role)
  207. def add_system_manager(email, first_name=None, last_name=None, send_welcome_email=False, password=None):
  208. # add user
  209. user = frappe.new_doc("User")
  210. user.update({
  211. "name": email,
  212. "email": email,
  213. "enabled": 1,
  214. "first_name": first_name or email,
  215. "last_name": last_name,
  216. "user_type": "System User",
  217. "send_welcome_email": 1 if send_welcome_email else 0
  218. })
  219. user.insert()
  220. # add roles
  221. roles = frappe.get_all('Role',
  222. fields=['name'],
  223. filters={
  224. 'name': ['not in', ('Administrator', 'Guest', 'All')]
  225. }
  226. )
  227. roles = [role.name for role in roles]
  228. user.add_roles(*roles)
  229. if password:
  230. from frappe.utils.password import update_password
  231. update_password(user=user.name, pwd=password)
  232. def get_enabled_system_users():
  233. # add more fields if required
  234. return frappe.get_all('User',
  235. fields=['email', 'language', 'name'],
  236. filters={
  237. 'user_type': 'System User',
  238. 'enabled': 1,
  239. 'name': ['not in', ('Administrator', 'Guest')]
  240. }
  241. )
  242. def is_website_user():
  243. return frappe.db.get_value('User', frappe.session.user, 'user_type') == "Website User"
  244. def is_system_user(username):
  245. return frappe.db.get_value("User", {"name": username, "enabled": 1, "user_type": "System User"})
  246. def get_users():
  247. from frappe.core.doctype.user.user import get_system_users
  248. users = []
  249. system_managers = frappe.utils.user.get_system_managers(only_name=True)
  250. for user in get_system_users():
  251. users.append({
  252. "full_name": frappe.utils.user.get_user_fullname(user),
  253. "email": user,
  254. "is_system_manager": 1 if (user in system_managers) else 0
  255. })
  256. return users
  257. def set_last_active_to_now(user):
  258. from frappe.utils import now_datetime
  259. frappe.db.set_value("User", user, "last_active", now_datetime())
  260. def reset_simultaneous_sessions(user_limit):
  261. for user in frappe.db.sql("""select name, simultaneous_sessions from tabUser
  262. where name not in ('Administrator', 'Guest') and user_type = 'System User' and enabled=1
  263. order by creation desc""", as_dict=1):
  264. if user.simultaneous_sessions < user_limit:
  265. user_limit = user_limit - user.simultaneous_sessions
  266. else:
  267. frappe.db.set_value("User", user.name, "simultaneous_sessions", 1)
  268. user_limit = user_limit - 1
  269. def get_link_to_reset_password(user):
  270. link = ''
  271. if not cint(frappe.db.get_single_value('System Settings', 'setup_complete')):
  272. user = frappe.get_doc("User", user)
  273. link = user.reset_password(send_email=False)
  274. frappe.db.commit()
  275. return {
  276. 'link': link
  277. }
  278. def get_users_with_role(role):
  279. return [p[0] for p in frappe.db.sql("""SELECT DISTINCT `tabUser`.`name`
  280. FROM `tabHas Role`, `tabUser`
  281. WHERE `tabHas Role`.`role`=%s
  282. AND `tabUser`.`name`!='Administrator'
  283. AND `tabHas Role`.`parent`=`tabUser`.`name`
  284. AND `tabUser`.`enabled`=1""", role)]