Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 
 

267 lignes
7.9 KiB

  1. # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
  2. # MIT License. See license.txt
  3. from __future__ import unicode_literals
  4. """
  5. Boot session from cache or build
  6. Session bootstraps info needed by common client side activities including
  7. permission, homepage, control panel variables, system defaults etc
  8. """
  9. import webnotes
  10. import conf
  11. import json
  12. from webnotes.utils import cint
  13. import webnotes.model.doctype
  14. import webnotes.defaults
  15. import webnotes.plugins
  16. @webnotes.whitelist()
  17. def clear(user=None):
  18. webnotes.local.session_obj.update(force=True)
  19. webnotes.local.conn.commit()
  20. clear_cache(webnotes.session.user)
  21. webnotes.response['message'] = "Cache Cleared"
  22. def clear_cache(user=None):
  23. cache = webnotes.cache()
  24. # clear doctype cache
  25. webnotes.model.doctype.clear_cache()
  26. # clear plugins code cache
  27. webnotes.plugins.clear_cache()
  28. if user:
  29. cache.delete_value("bootinfo:" + user)
  30. if webnotes.session:
  31. if user==webnotes.session.user and webnotes.session.sid:
  32. cache.delete_value("session:" + webnotes.session.sid)
  33. else:
  34. for sid in webnotes.conn.sql_list("""select sid from tabSessions
  35. where user=%s""", user):
  36. cache.delete_value("session:" + sid)
  37. else:
  38. for sess in webnotes.conn.sql("""select user, sid from tabSessions""", as_dict=1):
  39. cache.delete_value("sesssion:" + sess.sid)
  40. cache.delete_value("bootinfo:" + sess.user)
  41. def clear_sessions(user=None, keep_current=False):
  42. if not user:
  43. user = webnotes.session.user
  44. for sid in webnotes.conn.sql("""select sid from tabSessions where user=%s""", user):
  45. if keep_current and webnotes.session.sid==sid[0]:
  46. pass
  47. else:
  48. webnotes.cache().delete_value("session:" + sid[0])
  49. webnotes.conn.sql("""delete from tabSessions where sid=%s""", sid[0])
  50. def get():
  51. """get session boot info"""
  52. from core.doctype.notification_count.notification_count import get_notification_info_for_boot
  53. bootinfo = None
  54. if not getattr(conf,'auto_cache_clear',None):
  55. # check if cache exists
  56. bootinfo = webnotes.cache().get_value('bootinfo:' + webnotes.session.user)
  57. if bootinfo:
  58. bootinfo['from_cache'] = 1
  59. if not bootinfo:
  60. if not webnotes.cache().get_stats():
  61. webnotes.msgprint("memcached is not working / stopped. Please start memcached for best results.")
  62. # if not create it
  63. from webnotes.boot import get_bootinfo
  64. bootinfo = get_bootinfo()
  65. bootinfo["notification_info"] = get_notification_info_for_boot()
  66. webnotes.cache().set_value('bootinfo:' + webnotes.session.user, bootinfo)
  67. return bootinfo
  68. class Session:
  69. def __init__(self, user=None):
  70. self.user = user
  71. self.sid = webnotes.form_dict.get('sid') or webnotes.request.cookies.get('sid', 'Guest')
  72. self.data = webnotes._dict({'user':user,'data': webnotes._dict({})})
  73. self.time_diff = None
  74. if webnotes.form_dict.get('cmd')=='login':
  75. self.start()
  76. return
  77. self.load()
  78. def start(self):
  79. """start a new session"""
  80. import os
  81. import webnotes
  82. import webnotes.utils
  83. # generate sid
  84. if webnotes.local.login_manager.user=='Guest':
  85. sid = 'Guest'
  86. else:
  87. sid = webnotes.generate_hash()
  88. self.data['user'] = webnotes.local.login_manager.user
  89. self.data['sid'] = sid
  90. self.data['data']['user'] = webnotes.local.login_manager.user
  91. self.data['data']['session_ip'] = webnotes.get_request_header('REMOTE_ADDR')
  92. self.data['data']['last_updated'] = webnotes.utils.now()
  93. self.data['data']['session_expiry'] = self.get_expiry_period()
  94. self.data['data']['session_country'] = get_geo_ip_country(webnotes.get_request_header('REMOTE_ADDR'))
  95. # insert session
  96. webnotes.conn.begin()
  97. self.insert_session_record()
  98. # update profile
  99. webnotes.conn.sql("""UPDATE tabProfile SET last_login = '%s', last_ip = '%s'
  100. where name='%s'""" % (webnotes.utils.now(), webnotes.get_request_header('REMOTE_ADDR'), self.data['user']))
  101. webnotes.conn.commit()
  102. # set cookies to write
  103. webnotes.local.session = self.data
  104. def insert_session_record(self):
  105. webnotes.conn.sql("""insert into tabSessions
  106. (sessiondata, user, lastupdate, sid, status)
  107. values (%s , %s, NOW(), %s, 'Active')""",
  108. (str(self.data['data']), self.data['user'], self.data['sid']))
  109. # also add to memcache
  110. webnotes.cache().set_value("session:" + self.data.sid, self.data)
  111. def load(self):
  112. """non-login request: load a session"""
  113. import webnotes
  114. data = self.get_session_record()
  115. if data:
  116. # set language
  117. if data.lang and self.user!="demo@erpnext.com":
  118. webnotes.local.lang = data.lang
  119. self.data = webnotes._dict({'data': data,
  120. 'user':data.user, 'sid': self.sid})
  121. else:
  122. self.start_as_guest()
  123. def get_session_record(self):
  124. """get session record, or return the standard Guest Record"""
  125. r = self.get_session_data()
  126. if not r:
  127. webnotes.response["session_expired"] = 1
  128. self.sid = "Guest"
  129. r = self.get_session_data()
  130. return r
  131. def get_session_data(self):
  132. data = self.get_session_data_from_cache()
  133. if not data:
  134. data = self.get_session_data_from_db()
  135. return data
  136. def get_session_data_from_cache(self):
  137. data = webnotes._dict(webnotes.cache().get_value("session:" + self.sid) or {})
  138. if data:
  139. session_data = data.get("data", {})
  140. self.time_diff = webnotes.utils.time_diff_in_seconds(webnotes.utils.now(),
  141. session_data.get("last_updated"))
  142. expiry = self.get_expiry_in_seconds(session_data.get("session_expiry"))
  143. if self.time_diff > expiry:
  144. self.delete_session()
  145. data = None
  146. return data and data.data
  147. def get_session_data_from_db(self):
  148. if self.sid=="Guest":
  149. rec = webnotes.conn.sql("""select user, sessiondata from
  150. tabSessions where sid='Guest' """)
  151. else:
  152. rec = webnotes.conn.sql("""select user, sessiondata
  153. from tabSessions where sid=%s and
  154. TIMEDIFF(NOW(), lastupdate) < TIME(%s)""", (self.sid,
  155. self.get_expiry_period()))
  156. if rec:
  157. data = webnotes._dict(eval(rec and rec[0][1] or '{}'))
  158. data.user = rec[0][0]
  159. else:
  160. self.delete_session()
  161. data = None
  162. return data
  163. def get_expiry_in_seconds(self, expiry):
  164. if not expiry: return 3600
  165. parts = expiry.split(":")
  166. return (cint(parts[0]) * 3600) + (cint(parts[1]) * 60) + cint(parts[2])
  167. def delete_session(self):
  168. webnotes.cache().delete_value("session:" + self.sid)
  169. r = webnotes.conn.sql("""delete from tabSessions where sid=%s""", self.sid)
  170. def start_as_guest(self):
  171. """all guests share the same 'Guest' session"""
  172. webnotes.local.login_manager.login_as_guest()
  173. self.start()
  174. def update(self, force=False):
  175. """extend session expiry"""
  176. self.data['data']['last_updated'] = webnotes.utils.now()
  177. self.data['data']['lang'] = unicode(webnotes.lang)
  178. # update session in db
  179. time_diff = None
  180. last_updated = webnotes.cache().get_value("last_db_session_update:" + self.sid)
  181. if last_updated:
  182. time_diff = webnotes.utils.time_diff_in_seconds(webnotes.utils.now(),
  183. last_updated)
  184. if force or (webnotes.session['user'] != 'Guest' and \
  185. ((time_diff==None) or (time_diff > 1800))):
  186. # database persistence is secondary, don't update it too often
  187. webnotes.conn.sql("""update tabSessions set sessiondata=%s,
  188. lastupdate=NOW() where sid=%s""" , (str(self.data['data']),
  189. self.data['sid']))
  190. if webnotes.form_dict.cmd not in ("webnotes.sessions.clear", "logout"):
  191. webnotes.cache().set_value("last_db_session_update:" + self.sid,
  192. webnotes.utils.now())
  193. webnotes.cache().set_value("session:" + self.sid, self.data)
  194. def get_expiry_period(self):
  195. exp_sec = webnotes.defaults.get_global_default("session_expiry") or "06:00:00"
  196. # incase seconds is missing
  197. if exp_sec:
  198. if len(exp_sec.split(':')) == 2:
  199. exp_sec = exp_sec + ':00'
  200. else:
  201. exp_sec = "2:00:00"
  202. return exp_sec
  203. def get_geo_ip_country(ip_addr):
  204. try:
  205. import pygeoip
  206. except ImportError:
  207. return
  208. import os
  209. from webnotes.utils import get_base_path
  210. try:
  211. geo_ip_file = os.path.join(get_base_path(), "lib", "data", "GeoIP.dat")
  212. geo_ip = pygeoip.GeoIP(geo_ip_file, pygeoip.MEMORY_CACHE)
  213. return geo_ip.country_name_by_addr(ip_addr)
  214. except Exception, e:
  215. return