選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

profile.py 8.1 KiB

14年前
13年前
13年前
13年前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. # Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com)
  2. #
  3. # MIT License (MIT)
  4. #
  5. # Permission is hereby granted, free of charge, to any person obtaining a
  6. # copy of this software and associated documentation files (the "Software"),
  7. # to deal in the Software without restriction, including without limitation
  8. # the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9. # and/or sell copies of the Software, and to permit persons to whom the
  10. # Software is furnished to do so, subject to the following conditions:
  11. #
  12. # The above copyright notice and this permission notice shall be included in
  13. # all copies or substantial portions of the Software.
  14. #
  15. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  16. # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  17. # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  18. # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  19. # CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
  20. # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. #
  22. from __future__ import unicode_literals
  23. import webnotes
  24. class Profile:
  25. """
  26. A profile object is created at the beginning of every request with details of the use.
  27. The global profile object is `webnotes.user`
  28. """
  29. def __init__(self, name=''):
  30. self.name = name or webnotes.session.get('user')
  31. self.roles = []
  32. self.all_read = []
  33. self.can_create = []
  34. self.can_read = []
  35. self.can_write = []
  36. self.can_cancel = []
  37. self.can_search = []
  38. self.can_get_report = []
  39. self.allow_modules = []
  40. # for doctypes with create permission but are not supposed to be created using New
  41. self.in_create = []
  42. def _load_roles(self):
  43. self.roles = webnotes.get_roles()
  44. return self.roles
  45. def get_roles(self):
  46. """get list of roles"""
  47. if self.roles:
  48. return self.roles
  49. return self._load_roles()
  50. def build_doctype_map(self):
  51. """build map of special doctype properties"""
  52. self.doctype_map = {}
  53. for r in webnotes.conn.sql("""select name, in_create, issingle, istable,
  54. read_only, module from tabDocType""", as_dict=1):
  55. r['child_tables'] = []
  56. self.doctype_map[r['name']] = r
  57. for r in webnotes.conn.sql("""select parent, options from tabDocField
  58. where fieldtype="Table"
  59. and parent not like "old_parent:%%"
  60. and ifnull(docstatus,0)=0
  61. """):
  62. if r[0] in self.doctype_map:
  63. self.doctype_map[r[0]]['child_tables'].append(r[1])
  64. def build_perm_map(self):
  65. """build map of permissions at level 0"""
  66. self.perm_map = {}
  67. for r in webnotes.conn.sql("""select parent, `read`, `write`, `create`, `submit`, `cancel`
  68. from tabDocPerm where docstatus=0
  69. and ifnull(permlevel,0)=0
  70. and parent not like "old_parent:%%"
  71. and role in ('%s')""" % "','".join(self.get_roles()), as_dict=1):
  72. dt = r['parent']
  73. if not dt in self.perm_map:
  74. self.perm_map[dt] = {}
  75. for k in ('read', 'write', 'create', 'submit', 'cancel'):
  76. if not self.perm_map[dt].get(k):
  77. self.perm_map[dt][k] = r.get(k)
  78. def build_permissions(self):
  79. """build lists of what the user can read / write / create
  80. quirks:
  81. read_only => Not in Search
  82. in_create => Not in create
  83. """
  84. self.build_doctype_map()
  85. self.build_perm_map()
  86. for dt in self.doctype_map:
  87. dtp = self.doctype_map[dt]
  88. p = self.perm_map.get(dt, {})
  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. self.all_read.append(dt)
  100. else:
  101. self.can_read.append(dt)
  102. if p.get('cancel'):
  103. self.can_cancel.append(dt)
  104. if (p.get('read') or p.get('write') or p.get('create')):
  105. self.can_get_report.append(dt)
  106. self.can_get_report += dtp['child_tables']
  107. if not dtp.get('istable'):
  108. if not dtp.get('issingle') and not dtp.get('read_only'):
  109. self.can_search.append(dt)
  110. if not dtp.get('module') in self.allow_modules:
  111. self.allow_modules.append(dtp.get('module'))
  112. self.can_write += self.can_create
  113. self.can_write += self.in_create
  114. self.can_read += self.can_write
  115. self.all_read += self.can_read
  116. def get_defaults(self):
  117. """
  118. Get the user's default values based on user and role profile
  119. """
  120. roles = self.get_roles() + [self.name]
  121. res = webnotes.conn.sql("""select defkey, defvalue
  122. from `tabDefaultValue` where parent in ("%s") order by idx""" % '", "'.join(roles))
  123. self.defaults = {'owner': [self.name], "user": [self.name]}
  124. for rec in res:
  125. if not self.defaults.has_key(rec[0]):
  126. self.defaults[rec[0]] = []
  127. self.defaults[rec[0]].append(rec[1] or '')
  128. return self.defaults
  129. def get_hide_tips(self):
  130. try:
  131. return webnotes.conn.sql("select hide_tips from tabProfile where name=%s", self.name)[0][0] or 0
  132. except:
  133. return 0
  134. # update recent documents
  135. def update_recent(self, dt, dn):
  136. """
  137. Update the user's `Recent` list with the given `dt` and `dn`
  138. """
  139. conn = webnotes.conn
  140. import json
  141. # get list of child tables, so we know what not to add in the recent list
  142. child_tables = [t[0] for t in conn.sql('select name from tabDocType where ifnull(istable,0) = 1')]
  143. if not (dt in ['Print Format', 'Start Page', 'Event', 'ToDo', 'Search Criteria']) \
  144. and not (dt in child_tables):
  145. r = webnotes.conn.sql("select recent_documents from tabProfile where name=%s", \
  146. self.name)[0][0] or ''
  147. if '~~~' in r:
  148. r = '[]'
  149. rdl = json.loads(r or '[]')
  150. new_rd = [dt, dn]
  151. # clear if exists
  152. for i in range(len(rdl)):
  153. rd = rdl[i]
  154. if rd==new_rd:
  155. del rdl[i]
  156. break
  157. if len(rdl) > 19:
  158. rdl = rdl[:19]
  159. rdl = [new_rd] + rdl
  160. self.recent = json.dumps(rdl)
  161. webnotes.conn.sql("""update tabProfile set
  162. recent_documents=%s where name=%s""", (self.recent, self.name))
  163. def load_profile(self):
  164. """
  165. Return a dictionary of user properites to be stored in the session
  166. """
  167. t = webnotes.conn.sql("""select email, first_name, last_name,
  168. recent_documents, email_signature, theme, background_image
  169. from tabProfile where name = %s""", self.name)[0]
  170. if not self.can_read:
  171. self.build_permissions()
  172. d = webnotes.DictObj({})
  173. d['name'] = self.name
  174. d['email'] = t[0] or ''
  175. d['first_name'] = t[1] or ''
  176. d['last_name'] = t[2] or ''
  177. d['recent'] = t[3] or ''
  178. d.email_signature = t[4] or ""
  179. d.theme = t[5] or "Default"
  180. d.background_image = t[6] or ""
  181. d['hide_tips'] = self.get_hide_tips()
  182. d['roles'] = self.roles
  183. d['defaults'] = self.get_defaults()
  184. d['can_create'] = self.can_create
  185. d['can_write'] = self.can_write
  186. d['can_read'] = list(set(self.can_read))
  187. d['can_cancel'] = list(set(self.can_cancel))
  188. d['can_get_report'] = list(set(self.can_get_report))
  189. d['allow_modules'] = self.allow_modules
  190. d['all_read'] = self.all_read
  191. d['can_search'] = list(set(self.can_search))
  192. d['in_create'] = self.in_create
  193. return d
  194. def load_from_session(self, d):
  195. """
  196. Setup the user profile from the dictionary saved in the session (generated by `load_profile`)
  197. """
  198. self.can_create = d['can_create']
  199. self.can_read = d['can_read']
  200. self.can_write = d['can_write']
  201. self.can_search = d['can_search']
  202. self.can_cancel = d['can_cancel']
  203. self.can_get_report = d['can_get_report']
  204. self.allow_modules = d['allow_modules']
  205. self.all_read = d['all_read']
  206. self.in_create = d['in_create']
  207. self.roles = d['roles']
  208. self.defaults = d['defaults']
  209. def get_user_fullname(user):
  210. fullname = webnotes.conn.sql("SELECT CONCAT_WS(' ', first_name, last_name) FROM `tabProfile` WHERE name=%s", user)
  211. return fullname and fullname[0][0] or ''
  212. def get_system_managers():
  213. """returns all system manager's profile details"""
  214. system_managers = webnotes.conn.sql("""select distinct name
  215. from tabProfile p
  216. where docstatus < 2 and enabled = 1
  217. and name not in ("Administrator", "Guest")
  218. and exists (select * from tabUserRole ur
  219. where ur.parent = p.name and ur.role="System Manager")""")
  220. return [p[0] for p in system_managers]