190 lines
7.9 KiB
Python
190 lines
7.9 KiB
Python
import logging
|
|
from odoo import api, fields, models
|
|
from odoo.addons.databases.models.project_project import get_database_api_keys
|
|
|
|
from ..api import ApiError, OdooDatabaseApi
|
|
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class DatabasesInviteUsersWizard(models.TransientModel):
|
|
_name = 'databases.manage_users.wizard'
|
|
_description = 'Database Users Invitation Wizard'
|
|
|
|
database_ids = fields.Many2many(
|
|
comodel_name='project.project',
|
|
domain=[('database_hosting', 'not in', (False, 'other'))],
|
|
default=lambda self: self.env.context.get('active_ids')
|
|
)
|
|
mode = fields.Selection([
|
|
('invite', 'Invitation'),
|
|
('remove', 'Removal'),
|
|
], required=True)
|
|
state = fields.Selection([
|
|
('draft', 'Draft'),
|
|
('done', 'Done'),
|
|
], required=True, default='draft')
|
|
error_message = fields.Char(default='')
|
|
user_ids = fields.Many2many('res.users', domain=[('share', '=', False)])
|
|
summary_message = fields.Char(compute='_compute_summary_message')
|
|
everywhere_user_ids = fields.Many2many('res.users', compute='_compute_everywhere_user_ids')
|
|
removable_user_ids = fields.Many2many('res.users', compute='_compute_removable_user_ids')
|
|
|
|
@api.depends('database_ids')
|
|
def _compute_summary_message(self):
|
|
for record in self:
|
|
if record.state == 'draft':
|
|
if record.mode == 'invite':
|
|
if len(record.database_ids) == 1:
|
|
record.summary_message = self.env._(
|
|
"Select the users you want to invite to the database %(database_name)s.",
|
|
database_name=record.database_ids.name
|
|
)
|
|
else:
|
|
record.summary_message = self.env._(
|
|
"Select the users you want to invite to the %(nb_databases)s selected databases.",
|
|
nb_databases=len(record.database_ids)
|
|
)
|
|
else:
|
|
if len(record.database_ids) == 1:
|
|
record.summary_message = self.env._(
|
|
"Select the users you want to remove from the database %(database_name)s.",
|
|
database_name=record.database_ids.name
|
|
)
|
|
else:
|
|
record.summary_message = self.env._(
|
|
"Select the users you want to remove from the %(nb_databases)s selected databases.",
|
|
nb_databases=len(record.database_ids)
|
|
)
|
|
elif record.state == 'done':
|
|
if record.error_message:
|
|
record.summary_message = self.env._("An error occurred: %s", record.error_message)
|
|
elif record.mode == 'invite':
|
|
record.summary_message = self.env._(
|
|
"These users were successfully invited to %(nb_databases)s databases.",
|
|
nb_databases=len(record.database_ids)
|
|
)
|
|
else:
|
|
record.summary_message = self.env._(
|
|
"These users were successfully removed from %(nb_databases)s databases.",
|
|
nb_databases=len(record.database_ids)
|
|
)
|
|
|
|
@api.depends('database_ids.database_user_ids.local_user_id')
|
|
def _compute_everywhere_user_ids(self):
|
|
for rec in self:
|
|
if not rec.database_ids:
|
|
rec.everywhere_user_ids = None
|
|
continue
|
|
# Compute the intersection of local_user_ids in each database
|
|
dbit = iter(rec.database_ids)
|
|
everywhere_user_ids = next(dbit).database_user_ids.local_user_id
|
|
for db in dbit:
|
|
everywhere_user_ids &= db.database_user_ids.local_user_id
|
|
rec.everywhere_user_ids = everywhere_user_ids
|
|
|
|
@api.depends('database_ids.database_user_ids.local_user_id')
|
|
def _compute_removable_user_ids(self):
|
|
for rec in self:
|
|
rec.removable_user_ids = rec.database_ids.database_user_ids.local_user_id
|
|
|
|
def _open(self):
|
|
if self.mode == 'invite':
|
|
name = self.env._("Invitation is done")
|
|
elif self.mode == 'remove':
|
|
name = self.env._("User removal is done")
|
|
|
|
return {
|
|
'type': 'ir.actions.act_window',
|
|
'name': name,
|
|
'res_model': self._name,
|
|
'res_id': self.id,
|
|
'view_mode': 'form',
|
|
'target': 'new',
|
|
'views': [[False, 'form']],
|
|
}
|
|
|
|
def action_invite_users(self):
|
|
existing_users = {
|
|
(du.login, du.project_id.id)
|
|
for du in self.env['databases.user'].search([
|
|
('login', 'in', self.user_ids.mapped('login')),
|
|
('project_id', 'in', self.database_ids.ids),
|
|
])
|
|
}
|
|
new_users = self.env['databases.user'].create([
|
|
{
|
|
'project_id': db.id,
|
|
'login': user.login,
|
|
'name': user.name,
|
|
}
|
|
for db in self.database_ids
|
|
for user in self.user_ids
|
|
if (user.login, db.id) not in existing_users
|
|
])
|
|
|
|
database_api_keys = get_database_api_keys(new_users.project_id)
|
|
for db, db_users in new_users.grouped('project_id').items():
|
|
database_api_key = database_api_keys.get(db.id, '')
|
|
args = [db.database_url, db.database_name, db.database_api_login, database_api_key]
|
|
if not all(args):
|
|
self.error_message += self.env._(
|
|
"Error while connecting to %(url)s: We are missing the database name, the api login or the api key\n",
|
|
url=db.database_url,
|
|
)
|
|
db_users.unlink()
|
|
continue
|
|
db_api = OdooDatabaseApi(*args)
|
|
|
|
try:
|
|
db_api.invite_users(db_users.mapped('login'))
|
|
except ApiError as e:
|
|
_logger.warning('ApiError: Error while creating user on %s: %s', db.database_name, e.args[0])
|
|
self.error_message += self.env._(
|
|
"Error while creating users on %(dbname)s: %(message)s\n",
|
|
dbname=db.database_name,
|
|
message=e.args[0],
|
|
)
|
|
db_users.unlink()
|
|
continue
|
|
|
|
self.state = 'done'
|
|
return self._open()
|
|
|
|
def action_remove_users(self):
|
|
users_to_delete = self.env['databases.user'].search([
|
|
('login', 'in', self.user_ids.mapped('login')),
|
|
('project_id', 'in', self.database_ids.ids),
|
|
])
|
|
|
|
database_api_keys = get_database_api_keys(users_to_delete.project_id)
|
|
for db, db_users in users_to_delete.grouped('project_id').items():
|
|
database_api_key = database_api_keys.get(db.id, '')
|
|
args = [db.database_url, db.database_name, db.database_api_login, database_api_key]
|
|
if not all(args):
|
|
self.error_message += self.env._(
|
|
"Error while connecting to %(url)s: We are missing the database name, the api login or the api key\n",
|
|
url=db.database_url,
|
|
)
|
|
users_to_delete -= db_users
|
|
continue
|
|
db_api = OdooDatabaseApi(*args)
|
|
|
|
try:
|
|
db_api.remove_users(db_users.mapped('login'))
|
|
except ApiError as e:
|
|
_logger.warning('ApiError: Error while removing users from %s: %s', db.database_name, e.args[0])
|
|
self.error_message += self.env._(
|
|
"Error while removing users from %(dbname)s: %(message)s\n",
|
|
dbname=db.database_name,
|
|
message=e.args[0],
|
|
)
|
|
users_to_delete -= db_users
|
|
continue
|
|
|
|
users_to_delete.unlink()
|
|
|
|
self.state = 'done'
|
|
return self._open()
|