mirror of
https://github.com/bringout/oca-server-auth.git
synced 2026-04-21 13:52:07 +02:00
Initial commit: OCA Server Auth packages (29 packages)
This commit is contained in:
commit
3ed80311c4
1325 changed files with 127292 additions and 0 deletions
|
|
@ -0,0 +1,6 @@
|
|||
from . import res_users
|
||||
from . import ir_http
|
||||
from . import mail_thread
|
||||
from . import mail_message
|
||||
from . import impersonate_log
|
||||
from . import model
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
# Copyright (C) 2024 Akretion (<http://www.akretion.com>).
|
||||
# @author Kévin Roche <kevin.roche@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class ImpersonateLog(models.Model):
|
||||
_name = "impersonate.log"
|
||||
_description = "Impersonate Logs"
|
||||
|
||||
user_id = fields.Many2one(
|
||||
comodel_name="res.users",
|
||||
)
|
||||
impersonated_partner_id = fields.Many2one(
|
||||
comodel_name="res.partner",
|
||||
string="Logged as",
|
||||
)
|
||||
date_start = fields.Datetime(
|
||||
string="Start Date",
|
||||
)
|
||||
date_end = fields.Datetime(
|
||||
string="End Date",
|
||||
)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
# Copyright (C) 2024 Akretion (<http://www.akretion.com>).
|
||||
# @author Kévin Roche <kevin.roche@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import models
|
||||
from odoo.http import request
|
||||
|
||||
|
||||
class Http(models.AbstractModel):
|
||||
_inherit = "ir.http"
|
||||
|
||||
def session_info(self):
|
||||
session_info = super().session_info()
|
||||
session_info.update(
|
||||
{
|
||||
"is_impersonate_user": request.env.user._is_impersonate_user(),
|
||||
"impersonate_from_uid": request.session.impersonate_from_uid,
|
||||
}
|
||||
)
|
||||
return session_info
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
# Copyright (C) 2024 Akretion (<http://www.akretion.com>).
|
||||
# @author Kévin Roche <kevin.roche@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.http import request
|
||||
from odoo.tools import html_escape
|
||||
|
||||
|
||||
class Message(models.Model):
|
||||
_inherit = "mail.message"
|
||||
|
||||
impersonated_author_id = fields.Many2one(
|
||||
comodel_name="res.partner",
|
||||
compute="_compute_impersonated_author_id",
|
||||
store=True,
|
||||
)
|
||||
|
||||
body = fields.Html(
|
||||
compute="_compute_message_body",
|
||||
inverse="_inverse_message_body",
|
||||
store=True,
|
||||
readonly=False,
|
||||
)
|
||||
|
||||
@api.depends("author_id")
|
||||
def _compute_impersonated_author_id(self):
|
||||
for rec in self:
|
||||
if request and request.session.impersonate_from_uid:
|
||||
rec.impersonated_author_id = (
|
||||
self.env["res.users"]
|
||||
.browse(request.session.impersonate_from_uid)
|
||||
.partner_id.id
|
||||
)
|
||||
else:
|
||||
rec.impersonated_author_id = False
|
||||
|
||||
@api.depends("author_id", "impersonated_author_id")
|
||||
def _compute_message_body(self):
|
||||
for rec in self:
|
||||
additional_info = ""
|
||||
if (
|
||||
request
|
||||
and request.session.impersonate_from_uid
|
||||
and rec.impersonated_author_id
|
||||
):
|
||||
current_partner = (
|
||||
self.env["res.users"].browse(request.session.uid).partner_id
|
||||
)
|
||||
additional_info = _("Logged in as {}").format(
|
||||
html_escape(current_partner.name)
|
||||
)
|
||||
if rec.body and additional_info:
|
||||
rec.body = f"<b>{additional_info}</b><br/>{rec.body}"
|
||||
else:
|
||||
rec.body = rec.body
|
||||
|
||||
def _inverse_message_body(self):
|
||||
for rec in self:
|
||||
additional_info = ""
|
||||
if (
|
||||
request
|
||||
and request.session.impersonate_from_uid
|
||||
and rec.impersonated_author_id
|
||||
):
|
||||
current_partner = (
|
||||
self.env["res.users"].browse(request.session.uid).partner_id
|
||||
)
|
||||
additional_info = _("Logged in as {}").format(
|
||||
html_escape(current_partner.name)
|
||||
)
|
||||
if additional_info:
|
||||
start_with = f"<b>{additional_info}</b><br/>"
|
||||
if rec.body and rec.body.startswith(start_with):
|
||||
rec.body = rec.body
|
||||
else:
|
||||
rec.body = f"{start_with}{rec.body}"
|
||||
else:
|
||||
rec.body = rec.body
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
# Copyright (C) 2024 Akretion (<http://www.akretion.com>).
|
||||
# @author Kévin Roche <kevin.roche@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import models
|
||||
from odoo.http import request
|
||||
|
||||
|
||||
class MailThread(models.AbstractModel):
|
||||
_inherit = "mail.thread"
|
||||
|
||||
def _message_compute_author(
|
||||
self, author_id=None, email_from=None, raise_on_email=True
|
||||
):
|
||||
if request and request.session.impersonate_from_uid:
|
||||
author = self.env["res.users"].browse(request.session.uid).partner_id
|
||||
if author_id == author.id or author_id is None:
|
||||
impersonate_from_author = (
|
||||
self.env["res.users"]
|
||||
.browse(request.session.impersonate_from_uid)
|
||||
.partner_id
|
||||
)
|
||||
email = impersonate_from_author.email_formatted
|
||||
return impersonate_from_author.id, email
|
||||
|
||||
return super()._message_compute_author(
|
||||
author_id=author_id,
|
||||
email_from=email_from,
|
||||
raise_on_email=raise_on_email,
|
||||
)
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
# Copyright (C) 2024 Akretion (<http://www.akretion.com>).
|
||||
# @author Kévin Roche <kevin.roche@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import models
|
||||
from odoo.http import request
|
||||
|
||||
|
||||
class BaseModel(models.AbstractModel):
|
||||
_inherit = "base"
|
||||
|
||||
def _prepare_create_values(self, vals_list):
|
||||
result_vals_list = super()._prepare_create_values(vals_list)
|
||||
if (
|
||||
request
|
||||
and request.session.impersonate_from_uid
|
||||
and "create_uid" in self._fields
|
||||
):
|
||||
for vals in result_vals_list:
|
||||
vals["create_uid"] = request.session.impersonate_from_uid
|
||||
return result_vals_list
|
||||
|
||||
def write(self, vals):
|
||||
"""Overwrite the write_uid with the impersonating user"""
|
||||
res = super().write(vals)
|
||||
if (
|
||||
request
|
||||
and request.session.impersonate_from_uid
|
||||
and "write_uid" in self._fields
|
||||
):
|
||||
self._fields["write_uid"].write(self, request.session.impersonate_from_uid)
|
||||
return res
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
# Copyright 2024 Akretion (https://www.akretion.com).
|
||||
# @author Kévin Roche <kevin.roche@akretion.com>
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
|
||||
import logging
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.http import request
|
||||
from odoo.service import security
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Users(models.Model):
|
||||
_inherit = "res.users"
|
||||
|
||||
def _get_partner_name(self, user_id):
|
||||
return self.env["res.users"].browse(user_id).partner_id.name
|
||||
|
||||
def _is_impersonate_user(self):
|
||||
self.ensure_one()
|
||||
return self.has_group("impersonate_login.group_impersonate_login")
|
||||
|
||||
def impersonate_login(self):
|
||||
if request:
|
||||
if request.session.impersonate_from_uid:
|
||||
if self.id == request.session.impersonate_from_uid:
|
||||
return self.back_to_origin_login()
|
||||
else:
|
||||
raise UserError(_("You are already Logged as another user."))
|
||||
if self.id == request.session.uid:
|
||||
raise UserError(_("It's you."))
|
||||
if (
|
||||
request.env.user._is_impersonate_user()
|
||||
and request.env.user._is_internal()
|
||||
):
|
||||
target_uid = self.id
|
||||
request.session.impersonate_from_uid = self._uid
|
||||
request.session.uid = target_uid
|
||||
impersonate_log = (
|
||||
self.env["impersonate.log"]
|
||||
.sudo()
|
||||
.create(
|
||||
{
|
||||
"user_id": self._uid,
|
||||
"impersonated_partner_id": self.env["res.users"]
|
||||
.browse(target_uid)
|
||||
.partner_id.id,
|
||||
"date_start": fields.datetime.now(),
|
||||
}
|
||||
)
|
||||
)
|
||||
request.session.impersonate_log_id = impersonate_log.id
|
||||
logger.info(
|
||||
f"IMPERSONATE: {self._get_partner_name(self._uid)} "
|
||||
f"Login as {self._get_partner_name(self.id)}"
|
||||
)
|
||||
# invalidate session token cache as we've changed the uid
|
||||
request.env["res.users"].clear_caches()
|
||||
request.session.session_token = security.compute_session_token(
|
||||
request.session, request.env
|
||||
)
|
||||
|
||||
# reload the client; open the first available root menu
|
||||
menu = self.env["ir.ui.menu"].search([("parent_id", "=", False)])[:1]
|
||||
return {
|
||||
"type": "ir.actions.client",
|
||||
"tag": "reload",
|
||||
"params": {"menu_id": menu.id},
|
||||
}
|
||||
|
||||
@api.model
|
||||
def action_impersonate_login(self):
|
||||
if request:
|
||||
from_uid = request.session.impersonate_from_uid
|
||||
if not from_uid:
|
||||
action = self.env["ir.actions.act_window"]._for_xml_id(
|
||||
"base.action_res_users"
|
||||
)
|
||||
action["views"] = [[self.env.ref("base.view_users_tree").id, "tree"]]
|
||||
action["domain"] = [
|
||||
("id", "!=", self.env.user.id),
|
||||
("share", "=", False),
|
||||
]
|
||||
action["target"] = "new"
|
||||
return action
|
||||
|
||||
@api.model
|
||||
def back_to_origin_login(self):
|
||||
if request:
|
||||
from_uid = request.session.impersonate_from_uid
|
||||
if from_uid:
|
||||
request.session.uid = from_uid
|
||||
self.env["impersonate.log"].sudo().browse(
|
||||
request.session.impersonate_log_id
|
||||
).write(
|
||||
{
|
||||
"date_end": fields.datetime.now(),
|
||||
}
|
||||
)
|
||||
# invalidate session token cache as we've changed the uid
|
||||
request.env["res.users"].clear_caches()
|
||||
request.session.impersonate_from_uid = False
|
||||
request.session.impersonate_log_id = False
|
||||
request.session.session_token = security.compute_session_token(
|
||||
request.session, request.env
|
||||
)
|
||||
logger.info(
|
||||
f"IMPERSONATE: {self._get_partner_name(from_uid)} "
|
||||
f"Logout as {self._get_partner_name(self._uid)}"
|
||||
)
|
||||
|
||||
# reload the client; open the first available root menu
|
||||
menu = self.env["ir.ui.menu"].search([("parent_id", "=", False)])[:1]
|
||||
return {
|
||||
"type": "ir.actions.client",
|
||||
"tag": "reload",
|
||||
"params": {"menu_id": menu.id},
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue