res_users.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. # -*- coding: utf-8 -*-
  2. ##############################################################################
  3. #
  4. # OpenERP, Open Source Management Solution
  5. # Copyright (C) 2004-2013 OpenERP S.A. (<http://openerp.com>).
  6. #
  7. # Copyright (C) 2011-2015 Nevpro Business Solutions Pvt Ltd. (<http://www.nevpro.co.in>).
  8. #
  9. # This program is free software: you can redistribute it and/or modify
  10. # it under the terms of the GNU Affero General Public License as
  11. # published by the Free Software Foundation, either version 3 of the
  12. # License, or (at your option) any later version.
  13. #
  14. # This program is distributed in the hope that it will be useful,
  15. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. # GNU Affero General Public License for more details.
  18. #
  19. # You should have received a copy of the GNU Affero General Public License
  20. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. #
  22. ##############################################################################
  23. import logging
  24. import openerp
  25. from openerp.osv import fields, osv, orm
  26. from datetime import date,datetime,time,timedelta
  27. from openerp import SUPERUSER_ID
  28. from openerp.http import request
  29. from openerp.tools.translate import _
  30. from openerp.http import Response
  31. from openerp import http
  32. _logger = logging.getLogger(__name__)
  33. class Home(openerp.addons.web.controllers.main.Home):
  34. @http.route('/web/login', type='http', auth="none")
  35. def web_login(self, redirect=None, **kw):
  36. openerp.addons.web.controllers.main.ensure_db()
  37. if request.httprequest.method == 'GET' and redirect and request.session.uid:
  38. return http.redirect_with_hash(redirect)
  39. if not request.uid:
  40. request.uid = openerp.SUPERUSER_ID
  41. values = request.params.copy()
  42. if not redirect:
  43. redirect = '/web?' + request.httprequest.query_string
  44. values['redirect'] = redirect
  45. try:
  46. values['databases'] = http.db_list()
  47. except openerp.exceptions.AccessDenied:
  48. values['databases'] = None
  49. if request.httprequest.method == 'POST':
  50. old_uid = request.uid
  51. uid = request.session.authenticate(request.session.db, request.params['login'], request.params['password'])
  52. if uid is not False:
  53. return http.redirect_with_hash(redirect)
  54. request.uid = old_uid
  55. values['error'] = "Error de inicio de sesión debido a uno de los siguientes motivos"
  56. values['error2'] = "- Usuario / Contraseña Errónea"
  57. values['error3'] = "- El usuario ya inició sesión desde otro navegador"
  58. return request.render('web.login', values)
  59. class Root_new(openerp.http.Root):
  60. def get_response(self, httprequest, result, explicit_session):
  61. if isinstance(result, Response) and result.is_qweb:
  62. try:
  63. result.flatten()
  64. except(Exception), e:
  65. if request.db:
  66. result = request.registry['ir.http']._handle_exception(e)
  67. else:
  68. raise
  69. if isinstance(result, basestring):
  70. response = Response(result, mimetype='text/html')
  71. else:
  72. response = result
  73. if httprequest.session.should_save:
  74. self.session_store.save(httprequest.session)
  75. # We must not set the cookie if the session id was specified using a http header or a GET parameter.
  76. # There are two reasons to this:
  77. # - When using one of those two means we consider that we are overriding the cookie, which means creating a new
  78. # session on top of an already existing session and we don't want to create a mess with the 'normal' session
  79. # (the one using the cookie). That is a special feature of the Session Javascript class.
  80. # - It could allow session fixation attacks.
  81. if not explicit_session and hasattr(response, 'set_cookie'):
  82. response.set_cookie('session_id', httprequest.session.sid, max_age=2 * 60)
  83. return response
  84. root = Root_new()
  85. openerp.http.Root.get_response = root.get_response
  86. class res_users(osv.osv):
  87. _inherit = 'res.users'
  88. _columns = {
  89. 'session_id' : fields.char('Session ID', size=100),
  90. 'expiration_date' : fields.datetime('Expiration Date'),
  91. 'logged_in': fields.boolean('Logged in'),
  92. }
  93. def _login(self, db, login, password):
  94. cr = self.pool.cursor()
  95. cr.autocommit(True)
  96. user_id = super(res_users,self)._login(db, login, password)
  97. try:
  98. session_id = request.httprequest.session.sid
  99. temp_browse = self.browse(cr, SUPERUSER_ID, user_id)
  100. if isinstance(temp_browse, list): temp_browse = temp_browse[0]
  101. exp_date = temp_browse.expiration_date
  102. if exp_date and temp_browse.session_id:
  103. exp_date = datetime.strptime(exp_date,"%Y-%m-%d %H:%M:%S")
  104. if exp_date < datetime.utcnow() or temp_browse.session_id != session_id:
  105. raise openerp.exceptions.AccessDenied()
  106. self.save_session(cr,user_id)
  107. except openerp.exceptions.AccessDenied:
  108. user_id = False
  109. _logger.warn("User %s is already logged in into the system!", login)
  110. _logger.warn("Multiple sessions are not allowed for security reasons!")
  111. finally:
  112. cr.close()
  113. return user_id
  114. #clears session_id and session expiry from res.users
  115. def clear_session(self, cr, user_id):
  116. if isinstance(user_id, list): user_id = user_id[0]
  117. self.write(cr, SUPERUSER_ID, user_id, {'session_id':'','expiration_date':False,'logged_in':False})
  118. #insert session_id and session expiry into res.users
  119. def save_session(self, cr, user_id):
  120. if isinstance(user_id, list): user_id = user_id[0]
  121. exp_date = datetime.utcnow() + timedelta(minutes=2)
  122. sid = request.httprequest.session.sid
  123. self.write(cr, SUPERUSER_ID, user_id, {'session_id':sid,'expiration_date':exp_date,'logged_in':True})
  124. #schedular function to validate users session
  125. def validate_sessions(self, cr, uid):
  126. ids = self.search(cr,SUPERUSER_ID,[('expiration_date','!=',False)])
  127. users = self.browse(cr, SUPERUSER_ID, ids)
  128. for user_id in users:
  129. exp_date = datetime.strptime(user_id.expiration_date,"%Y-%m-%d %H:%M:%S")
  130. if exp_date < datetime.utcnow():
  131. self.clear_session(cr, user_id.id)