You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

146 lines
6.4 KiB

# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Abhijith PG (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
import pickle
from ast import literal_eval
from datetime import timedelta
import odoo
from odoo import api, fields, models
from odoo.exceptions import ValidationError
from odoo.http import request
from odoo.tools._vendor import sessions
class UserSessionLogin(models.Model):
"""
Model to store user session login information. Contains information like
user_id, login_date, logout_date, session duration, device details,
IP address, etc.
"""
_name = "user.session.login"
_description = "User Session Login"
status = fields.Selection(selection=[('normal', ''),
('done', ''),
('blocked', '')], string='Status',
help="Status of the user session")
name = fields.Char(string='Name', help="Sequence number of the session.")
user_id = fields.Many2one('res.users', string="User", help="Session user")
sid = fields.Char(string='Session ID', help="Session id")
login_date = fields.Datetime(string='Login Date', help="Session login date")
logout_date = fields.Datetime(string='Logout Date',
help="Session logout date")
session_duration = fields.Char(string='Session Duration',
help="Duration of the session",
compute='_compute_session_duration')
device = fields.Char(string='Device',
help="Device from which the session is created")
os = fields.Char(string='OS',
help="Operating System from which the session is created")
browser = fields.Char(string='Browser',
help="Browser on which the session is logged in")
ip_address = fields.Char(string='IP', help="IP address of the device")
state = fields.Selection(selection=[('active', 'Active'),
('closed', 'Closed')],
string='Status', help="State of the session.")
activity_ids = fields.One2many('user.session.activity', 'login_id',
string='Activities',
readonly=True,
help="All the activities in the selected "
"models in the session")
@api.model
def create(self, vals_list):
"""Updating the session sequence when creating a new session record"""
if not vals_list.get('name'):
vals_list['name'] = self.env['ir.sequence'].next_by_code(
'user.session.login.name') or ""
res = super().create(vals_list)
if request and request.session:
request.session.usm_session_id = res.id
return res
@api.depends('login_date', 'logout_date')
def _compute_session_duration(self):
"""Compute session duration"""
self.session_duration = 0
for rec in self:
if rec.login_date and rec.logout_date:
rec.session_duration = str(rec.logout_date - rec.login_date)
else:
rec.session_duration = 0
def unlink(self):
"""
Raises a `ValidationError` if any of the User Session Login records
being deleted have an active session. Only logged-out session user
session records can be deleted.
"""
for rec in self:
if not rec.logout_date:
raise ValidationError(
"%s is active. Only logged out session records can be "
"deleted" % rec.name)
return super().unlink()
def action_button_force_logout(self):
"""Logs out the user by clearing the session data."""
self.ensure_one()
self.update({'state': 'closed',
'status': 'blocked'})
state_mapped = self.env['user.session.login'].sudo().search(
[('user_id', '=', self.user_id.id)]).mapped('state')
if 'active' not in state_mapped:
self.sudo().user_id.status = 'blocked'
try:
self.update({'logout_date': fields.Datetime.now()})
path = odoo.tools.config.session_dir
store = sessions.FilesystemSessionStore(
path, session_class=odoo.http.OpenERPSession,
renew_missing=True)
session_fname = store.get_session_filename(self.sid)
sess_file = open(session_fname, 'rb')
sess = pickle.load(sess_file)
# updating the sess file
sess['login'] = None
sess['uid'] = None
sess['session_token'] = None
sess['context'] = {}
sess_file = open(session_fname, 'wb')
pickle.dump(sess, sess_file)
except FileNotFoundError:
self.update({'logout_date': fields.Datetime.now()})
def clear_records(self):
"""
Clears all the user session records that have a logout_date older
than the number of days specified in the settings.
"""
records = self.search([])
for rec in records:
if rec.logout_date and fields.Datetime.now() > rec.logout_date + \
timedelta(days=literal_eval(
self.env['ir.config_parameter'].sudo().get_param(
'user_session_management.records_retain_period')))\
and self.env['ir.config_parameter'].sudo().get_param(
'user_session_management.clear_log'):
rec.activity_ids.unlink()
rec.unlink()