Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

272 linhas
8.0 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 datetime
  5. from frappe import _
  6. import frappe
  7. import frappe.database
  8. import frappe.utils
  9. import frappe.utils.user
  10. from frappe import conf
  11. from frappe.sessions import Session, clear_sessions, delete_session
  12. from frappe.modules.patch_handler import check_session_stopped
  13. from urllib import quote
  14. class HTTPRequest:
  15. def __init__(self):
  16. # Get Environment variables
  17. self.domain = frappe.request.host
  18. if self.domain and self.domain.startswith('www.'):
  19. self.domain = self.domain[4:]
  20. if frappe.get_request_header('X-Forwarded-For'):
  21. frappe.local.request_ip = frappe.get_request_header('X-Forwarded-For')
  22. elif frappe.get_request_header('REMOTE_ADDR'):
  23. frappe.local.request_ip = frappe.get_request_header('REMOTE_ADDR')
  24. else:
  25. frappe.local.request_ip = '127.0.0.1'
  26. # language
  27. self.set_lang(frappe.request.accept_languages.values())
  28. # load cookies
  29. frappe.local.cookie_manager = CookieManager()
  30. # override request method. All request to be of type POST, but if _type == "POST" then commit
  31. if frappe.form_dict.get("_type"):
  32. frappe.local.request_method = frappe.form_dict.get("_type")
  33. del frappe.form_dict["_type"]
  34. # set db
  35. self.connect()
  36. # login
  37. frappe.local.login_manager = LoginManager()
  38. # write out latest cookies
  39. frappe.local.cookie_manager.init_cookies()
  40. # check status
  41. check_session_stopped()
  42. # run login triggers
  43. if frappe.form_dict.get('cmd')=='login':
  44. frappe.local.login_manager.run_trigger('on_session_creation')
  45. def set_lang(self, lang_codes):
  46. from frappe.translate import guess_language
  47. frappe.local.lang = guess_language(lang_codes)
  48. def get_db_name(self):
  49. """get database name from conf"""
  50. return conf.db_name
  51. def connect(self, ac_name = None):
  52. """connect to db, from ac_name or db_name"""
  53. frappe.local.db = frappe.database.Database(user = self.get_db_name(), \
  54. password = getattr(conf,'db_password', ''))
  55. class LoginManager:
  56. def __init__(self):
  57. self.user = None
  58. self.info = None
  59. self.full_name = None
  60. self.user_type = None
  61. if frappe.local.form_dict.get('cmd')=='login' or frappe.local.request.path=="/api/method/login":
  62. self.login()
  63. else:
  64. self.make_session(resume=True)
  65. def login(self):
  66. # clear cache
  67. frappe.clear_cache(user = frappe.form_dict.get('usr'))
  68. self.authenticate()
  69. self.post_login()
  70. def post_login(self):
  71. self.info = frappe.db.get_value("User", self.user,
  72. ["user_type", "first_name", "last_name", "user_image"], as_dict=1)
  73. self.full_name = " ".join(filter(None, [self.info.first_name, self.info.last_name]))
  74. self.user_type = self.info.user_type
  75. self.run_trigger('on_login')
  76. self.validate_ip_address()
  77. self.validate_hour()
  78. self.make_session()
  79. self.set_user_info()
  80. def set_user_info(self):
  81. # set sid again
  82. frappe.local.cookie_manager.init_cookies()
  83. if self.info.user_type=="Website User":
  84. frappe.local.cookie_manager.set_cookie("system_user", "no")
  85. frappe.local.response["message"] = "No App"
  86. else:
  87. frappe.local.cookie_manager.set_cookie("system_user", "yes")
  88. frappe.local.response['message'] = 'Logged In'
  89. frappe.response["full_name"] = self.full_name
  90. frappe.local.cookie_manager.set_cookie("full_name", self.full_name)
  91. frappe.local.cookie_manager.set_cookie("user_id", self.user)
  92. frappe.local.cookie_manager.set_cookie("user_image", self.info.user_image or "")
  93. def make_session(self, resume=False):
  94. # start session
  95. frappe.local.session_obj = Session(user=self.user, resume=resume,
  96. full_name=self.full_name, user_type=self.user_type)
  97. # reset user if changed to Guest
  98. self.user = frappe.local.session_obj.user
  99. frappe.local.session = frappe.local.session_obj.data
  100. self.clear_active_sessions()
  101. def clear_active_sessions(self):
  102. if not frappe.conf.get("deny_multiple_sessions"):
  103. return
  104. if frappe.session.user != "Guest":
  105. clear_sessions(frappe.session.user, keep_current=True)
  106. def authenticate(self, user=None, pwd=None):
  107. if not (user and pwd):
  108. user, pwd = frappe.form_dict.get('usr'), frappe.form_dict.get('pwd')
  109. if not (user and pwd):
  110. self.fail('Incomplete login details')
  111. self.check_if_enabled(user)
  112. self.user = self.check_password(user, pwd)
  113. def check_if_enabled(self, user):
  114. """raise exception if user not enabled"""
  115. from frappe.utils import cint
  116. if user=='Administrator': return
  117. if not cint(frappe.db.get_value('User', user, 'enabled')):
  118. self.fail('User disabled or missing')
  119. def check_password(self, user, pwd):
  120. """check password"""
  121. user = frappe.db.sql("""select `user` from __Auth where `user`=%s
  122. and `password`=password(%s)""", (user, pwd))
  123. if not user:
  124. self.fail('Incorrect password')
  125. else:
  126. return user[0][0] # in correct case
  127. def fail(self, message):
  128. frappe.local.response['message'] = message
  129. raise frappe.AuthenticationError
  130. def run_trigger(self, event='on_login'):
  131. for method in frappe.get_hooks().get(event, []):
  132. frappe.call(frappe.get_attr(method), login_manager=self)
  133. def validate_ip_address(self):
  134. """check if IP Address is valid"""
  135. ip_list = frappe.db.get_value('User', self.user, 'restrict_ip', ignore=True)
  136. if not ip_list:
  137. return
  138. ip_list = ip_list.replace(",", "\n").split('\n')
  139. ip_list = [i.strip() for i in ip_list]
  140. for ip in ip_list:
  141. if frappe.local.request_ip.startswith(ip):
  142. return
  143. frappe.throw(_("Not allowed from this IP Address"), frappe.AuthenticationError)
  144. def validate_hour(self):
  145. """check if user is logging in during restricted hours"""
  146. login_before = int(frappe.db.get_value('User', self.user, 'login_before', ignore=True) or 0)
  147. login_after = int(frappe.db.get_value('User', self.user, 'login_after', ignore=True) or 0)
  148. if not (login_before or login_after):
  149. return
  150. from frappe.utils import now_datetime
  151. current_hour = int(now_datetime().strftime('%H'))
  152. if login_before and current_hour > login_before:
  153. frappe.throw(_("Login not allowed at this time"), frappe.AuthenticationError)
  154. if login_after and current_hour < login_after:
  155. frappe.throw(_("Login not allowed at this time"), frappe.AuthenticationError)
  156. def login_as_guest(self):
  157. """login as guest"""
  158. self.login_as("Guest")
  159. def login_as(self, user):
  160. self.user = user
  161. self.post_login()
  162. def logout(self, arg='', user=None):
  163. if not user: user = frappe.session.user
  164. self.run_trigger('on_logout')
  165. if user == frappe.session.user:
  166. delete_session(frappe.session.sid)
  167. self.clear_cookies()
  168. else:
  169. clear_sessions(user)
  170. def clear_cookies(self):
  171. clear_cookies()
  172. class CookieManager:
  173. def __init__(self):
  174. self.cookies = {}
  175. self.to_delete = []
  176. def init_cookies(self):
  177. if not frappe.local.session.get('sid'): return
  178. # sid expires in 3 days
  179. expires = datetime.datetime.now() + datetime.timedelta(days=3)
  180. if frappe.session.sid:
  181. self.cookies["sid"] = {"value": frappe.session.sid, "expires": expires}
  182. if frappe.session.session_country:
  183. self.cookies["country"] = {"value": frappe.session.get("session_country")}
  184. def set_cookie(self, key, value, expires=None):
  185. self.cookies[key] = {"value": value, "expires": expires}
  186. def delete_cookie(self, to_delete):
  187. if not isinstance(to_delete, (list, tuple)):
  188. to_delete = [to_delete]
  189. self.to_delete.extend(to_delete)
  190. def flush_cookies(self, response):
  191. for key, opts in self.cookies.items():
  192. response.set_cookie(key, quote((opts.get("value") or "").encode('utf-8')),
  193. expires=opts.get("expires"))
  194. # expires yesterday!
  195. expires = datetime.datetime.now() + datetime.timedelta(days=-1)
  196. for key in set(self.to_delete):
  197. response.set_cookie(key, "", expires=expires)
  198. def _update_password(user, password):
  199. frappe.db.sql("""insert into __Auth (user, `password`)
  200. values (%s, password(%s))
  201. on duplicate key update `password`=password(%s)""", (user,
  202. password, password))
  203. @frappe.whitelist()
  204. def get_logged_user():
  205. return frappe.session.user
  206. def clear_cookies():
  207. if hasattr(frappe.local, "session"):
  208. frappe.session.sid = ""
  209. frappe.local.cookie_manager.delete_cookie(["full_name", "user_id", "sid", "user_image", "system_user"])