marc look at .repos/bemade-addons/bemade_mailcow_blacklist/static/src/js/mailcow_mailbox.js please

This commit is contained in:
Benoît Vézina 2023-06-29 20:22:25 -04:00
parent 68dd96a5a8
commit ed021edc40
11 changed files with 138 additions and 40 deletions

View file

@ -21,7 +21,7 @@ Main Features:
'license': 'OPL-1',
'author': 'BeMade',
'website': 'https://www.bemade.org',
'depends': ['mail', 'bemade_user_password_bundle'],
'depends': ['hr', 'mail', 'bemade_user_password_bundle'],
'data': [
'security/ir.model.access.csv',
'views/res_config_settings_views.xml',
@ -31,6 +31,11 @@ Main Features:
'views/res_users_views.xml',
],
"assets": {
"web.assets_backend": [
"bemade_mailcow_blacklist/static/src/js/mailcow_mailbox.js"
]
},
'demo': [],
'installable': True,
'application': False,

View file

@ -6,15 +6,25 @@ class MailAlias(models.Model):
mailcow_id = fields.One2many('mail.mailcow.alias', 'alias_id')
@api.model
def create(self, vals):
alias = super(MailAlias, self).create(vals)
mailcow_alias = self.env['mail.mailcow.alias'].search([('address', '=', alias.alias_name + '@' + alias.alias_domain)])
alias_domain = self.env["ir.config_parameter"].sudo().get_param("mail.catchall.domain"),
catchall_alias = self.env["ir.config_parameter"].sudo().get_param("mail.catchall.alias"),
alias_domain = alias_domain[0]
catchall_alias = catchall_alias[0]
if not alias_domain:
raise ValidationError(_("No catchall domain is set in the system parameters. Please set one and try again."))
mailcow_alias = self.env['mail.mailcow.alias'].search([('address', '=', alias.alias_name + '@' + alias_domain)])
if mailcow_alias:
mailcow_alias.write({'active': True})
else:
self.env['mail.mailcow.alias'].create({
'address': alias.alias_name + '@' + alias.alias_domain,
'goto': alias.alias_defaults.get('email_from', False),
'address': alias.alias_name + '@' + alias_domain,
'goto': catchall_alias + '@' + alias_domain,
'alias_id': alias.id,
})
return alias

View file

@ -1,8 +1,10 @@
# -*- coding: utf-8 -*-
from odoo import models, fields, api, exceptions
from odoo import models, fields, api, _
import requests
import logging
from odoo.exceptions import ValidationError
_logger = logging.getLogger(__name__)
@ -10,15 +12,29 @@ class MailMailcow(models.AbstractModel):
_name = 'mail.mailcow'
_description = 'Mailcow API'
@property
def get_credentials(self):
params = self.env['ir.config_parameter'].sudo()
return {
'base_url': params.get_param('mailcow.base_url'),
'api_key': params.get_param('mailcow.api_key'),
}
base_url = params.get_param('mailcow.base_url'),
base_url = base_url[0]
api_key = params.get_param('mailcow.api_key'),
api_key = api_key[0]
if not base_url or not api_key:
_logger.error('No API key or base URL is set in the system parameters')
raise ValidationError(_("No API key or base URL is set in the system parameters. Please set one and try again."))
# return False
else:
return {
'base_url': base_url,
'api_key': api_key
}
def api_request(self, endpoint, method='GET', data=None):
creds = self.get_credentials()
creds = self.get_credentials
if not creds:
return False
url = creds['base_url'] + endpoint
headers = {
'accept': 'application/json',

View file

@ -33,9 +33,10 @@ class MailcowAlias(models.Model):
"private_comment": f"Created by {self.env.user.name} on {fields.Datetime.now()}",
"public_comment": "Alias created in Odoo"
}
result = self.env['mail.mailcow'].api_request('api/v1/add/alias', 'POST', data)
result = self.env['mail.mailcow'].api_request('/api/v1/add/alias', 'POST', data)
if not result:
raise ValidationError(_("Failed to create alias on Mailcow server."))
#pass
raise ValidationError("Failed to create alias on Mailcow server.")
return alias
@ -59,7 +60,7 @@ class MailcowAlias(models.Model):
},
"items": [record.mc_id]
}
result = self.env['mail.mailcow'].api_request('api/v1/edit/alias', 'POST', data)
result = self.env['mail.mailcow'].api_request('/api/v1/edit/alias', 'POST', data)
if not result:
raise ValidationError(_("Failed to update alias on Mailcow server."))
@ -72,7 +73,7 @@ class MailcowAlias(models.Model):
For each alias fetched from Mailcow server, it tries to find a matching record
in Odoo. If it doesn't exist, it creates a new record.
"""
endpoint = 'api/v1/get/alias/all'
endpoint = '/api/v1/get/alias/all'
mailcow_aliases = self.api_request(endpoint)
if not mailcow_aliases:
@ -80,6 +81,7 @@ class MailcowAlias(models.Model):
for mc_alias in mailcow_aliases:
domain = mc_alias['domain']
alias_domain = self.env['ir.config_parameter'].sudo().get_param('mail.catchall.domain')
if domain == alias_domain:
alias = self.search([('address', '=', mc_alias['address'])], limit=1)

View file

@ -10,8 +10,8 @@ class MailcowBlacklist(models.Model):
_description = 'Mailcow Blacklist'
_inherit = ['mail.mailcow', 'mail.thread', 'mail.activity.mixin']
email = fields.Char(string='Email', required=True, track_visibility='onchange')
prefid = fields.Integer(string='Mailcow ID', required=True, track_visibility='onchange')
email = fields.Char(string='Email', required=True, tracking=True)
prefid = fields.Integer(string='Mailcow ID', required=True, tracking=True)
@api.model
def create(self, vals):
@ -19,10 +19,10 @@ class MailcowBlacklist(models.Model):
Overridden create method to add the new blacklist entry to the Mailcow server.
"""
res = super().create(vals)
domain = self.env['res.config.settings'].get_values()['mail.catchall.domain']
domain = self.env['ir.config_parameter'].sudo().get_param('mail.catchall.domain')
endpoint_add = 'api/v1/add/domain-policy'
endpoint_get_bl = f"api/v1/get/policy_bl_domain/{domain}"
endpoint_add = '/api/v1/add/domain-policy'
endpoint_get_bl = f"/api/v1/get/policy_bl_domain/{domain}"
data = {
'domain': domain,
'object_from': res.email,
@ -42,8 +42,8 @@ class MailcowBlacklist(models.Model):
old_email = self.email
res = super().write(vals)
if 'email' in vals:
delete_endpoint = 'api/v1/delete/domain-policy'
add_endpoint = 'api/v1/add/domain-policy'
delete_endpoint = '/api/v1/delete/domain-policy'
add_endpoint = '/api/v1/add/domain-policy'
delete_data = {
'items': [old_email]
}
@ -60,7 +60,7 @@ class MailcowBlacklist(models.Model):
Overridden unlink method to remove the blacklist entry from the Mailcow server.
"""
for record in self:
endpoint = 'api/v1/delete/blacklist'
endpoint = '/api/v1/delete/blacklist'
data = {
'items': [record.email]
}

View file

@ -11,13 +11,16 @@ class MailcowMailbox(models.Model):
_inherit = ['mail.mailcow', 'mail.thread', 'mail.activity.mixin']
_description = 'Mailcow Mailbox'
name = fields.Char(track_visibility='onchange')
address = fields.Char(compute='_compute_address', store=True, readonly=True, track_visibility='onchange')
local_part = fields.Char(required=True, track_visibility='onchange')
domain = fields.Char(required=True, track_visibility='onchange')
active = fields.Boolean(default=True, track_visibility='onchange')
user_id = fields.Many2one('res.users', ondelete='cascade', track_visibility='onchange')
password = fields.Char(readonly=True, track_visibility='onchange')
def _default_domain(self):
return self.env["ir.config_parameter"].sudo().get_param("mail.catchall.domain")
name = fields.Char(tracking=True)
address = fields.Char(compute='_compute_address', store=True, readonly=True, tracking=True)
local_part = fields.Char(required=True, tracking=True)
domain = fields.Char(required=True, tracking=True, default=_default_domain)
active = fields.Boolean(default=True, tracking=True)
user_id = fields.Many2one('res.users', ondelete='cascade', tracking=True)
password = fields.Char(readonly=True, tracking=True)
@api.depends('local_part', 'domain')
def _compute_address(self):
@ -28,7 +31,7 @@ class MailcowMailbox(models.Model):
"""
Synchronize Mailcow mailboxes with Odoo
"""
endpoint = 'api/v1/get/mailbox/all'
endpoint = '/api/v1/get/mailbox/all'
data = self.api_request(endpoint)
if data:
for item in data:
@ -51,12 +54,12 @@ class MailcowMailbox(models.Model):
vals['password'] = password
# Check if email exists on Mailcow
endpoint = f"api/v1/get/mailbox/{vals['address']}"
endpoint = f"/api/v1/get/mailbox/{vals['local_part']}@{vals['domain']}"
response = self.api_request(endpoint)
if not response:
# If email does not exist on Mailcow, create it
endpoint = 'api/v1/add/mailbox'
endpoint = '/api/v1/add/mailbox'
data = {
'local_part': vals['local_part'],
'domain': vals['domain'],
@ -70,7 +73,7 @@ class MailcowMailbox(models.Model):
'tls_enforce_out': "0",
}
self.api_request(endpoint, method='POST', data=data)
_logger.info(f'Mailbox {vals["address"]} has been created on Mailcow server')
_logger.info(f"Mailbox {vals['local_part']}@{vals['domain']} has been created on Mailcow server")
return super().create(vals)
@ -79,7 +82,7 @@ class MailcowMailbox(models.Model):
Override the write function to update a Mailcow mailbox whenever a user is updated in Odoo.
"""
if 'active' in vals or 'local_part' in vals or 'domain' in vals:
endpoint = f'api/v1/edit/mailbox/{self.address}'
endpoint = f'/api/v1/edit/mailbox/{self.address}'
data = {
'items': [self.address],
'attr': {
@ -97,7 +100,7 @@ class MailcowMailbox(models.Model):
"""
Override the unlink function to delete a Mailcow mailbox whenever a user is deleted in Odoo.
"""
endpoint = f'api/v1/delete/mailbox/{self.address}'
endpoint = f'/api/v1/delete/mailbox/{self.address}'
self.api_request(endpoint, method='POST')
_logger.info(f'Mailbox {self.address} has been deleted on Mailcow server')
@ -119,7 +122,7 @@ class MailcowMailbox(models.Model):
'name': user.name,
'password': user.password,
}
endpoint = 'api/v1/add/mailbox'
endpoint = '/api/v1/add/mailbox'
self.api_request(endpoint, method='POST', data=data)
_logger.info(f'Mailbox for user {user.login} has been created on Mailcow server')

View file

@ -5,10 +5,11 @@ class ResUsers(models.Model):
mailcow_mailbox = fields.Boolean(string='Mailcow Mailbox', default=False)
@api.model
def create(self, vals):
res = super(ResUsers, self).create(vals)
if vals.get('mailcow_mailbox'):
if vals.get('mailcow_mailbox', false):
self.env['mail.mailcow.mailbox'].create_mailbox_for_user(res)
return res

View file

@ -0,0 +1,30 @@
odoo.define('bemade_mailcow_blacklist.mailcow_mailbox', function (require) {
"use strict";
var core = require('web.core');
var ListController = require('web.ListController');
var ListView = require('web.ListView');
var viewRegistry = require('web.view_registry');
var MailboxesListController = ListController.extend({
buttons_template: 'mail.mailcow_mailbox_list_view_buttons',
events: _.extend({}, ListController.prototype.events, {
'click .o_button_sync_mailboxes': '_onSyncMailboxes',
}),
_onSyncMailboxes: function () {
this._rpc({
model: 'mail.mailcow.mailbox',
method: 'sync_mailboxes',
args: [],
});
},
});
var MailboxesListView = ListView.extend({
config: _.extend({}, ListView.prototype.config, {
Controller: MailboxesListController,
}),
});
viewRegistry.add('mail.mailcow.mailbox', MailboxesListView);
});

View file

@ -0,0 +1 @@
from . import test_mailcow

View file

@ -0,0 +1,12 @@
from odoo.tests.common import TransactionCase, tagged
@tagged('-at_install', 'post_install')
class TestMailcow(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
def test_new_mail_alias(self):
model_id = self.env['ir.model']._get('res.partner').id
self.alias = self.env['mail.alias'].create({'alias_name': 'test', 'alias_model_id': model_id})

View file

@ -1,10 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="mailcow_mailbox_view_tree" model="ir.ui.view">
<record id="view_mailcow_mailbox_tree" model="ir.ui.view">
<field name="name">mailcow.mailbox.view.tree</field>
<field name="model">mail.mailcow.mailbox</field>
<field name="arch" type="xml">
<tree string="Mailbox" decoration-info="active == False">
<header>
<button name="sync_mailboxes" string="Sync with Mailcow" type="object"/>
</header>
<field name="active"/>
<field name="name"/>
<field name="local_part"/>
@ -39,7 +42,7 @@
</field>
</record>
<record id="mailcow_mailbox_action" model="ir.actions.act_window">
<record id="action_mailcow_mailbox" model="ir.actions.act_window">
<field name="name">Mailboxes</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">mail.mailcow.mailbox</field>
@ -62,6 +65,21 @@
<menuitem id="mailcow_menu_mailbox"
name="Mailboxes"
parent="mailcow_menu"
action="mailcow_mailbox_action"
action="action_mailcow_mailbox"
sequence="10"/>
<record id="action_server_sync_mailboxes" model="ir.actions.server">
<field name="name">Sync Mailboxes</field>
<field name="model_id" ref="model_mail_mailcow_mailbox"/>
<field name="state">code</field>
<field name="code">model.sync_mailboxes()</field>
</record>
<record id="action_sync_mailboxes" model="ir.actions.act_window.view">
<field name="sequence" eval="10"/>
<field name="view_mode">tree</field>
<field name="act_window_id" ref="action_mailcow_mailbox"/>
<field name="view_id" ref="view_mailcow_mailbox_tree"/>
</record>
</odoo>