Define schedule actions Odoo 9

Schedule actions can be set by adding this code in your xml file. This exemple will call the function schedule_action from the model hr.employee and send a notification by email if the boolean enable_send_notification is True.

<record id="ir_cron_schedule_action" model="ir.cron">
   <field name="name">Schedule actions</field>
   <field name="user_id" ref="base.user_root" />
   <field name="interval_number">1</field>
   <field name="interval_type">days</field>
   <field name="numbercall">-1</field>
   <field eval="False" name="doall" />
   <field eval="'hr.employee'" name="model" />
   <field eval="'schedule_action'" name="function" />
</record>

This model inherits hr.employee and defines 1 additional field, and 2 additional functions. send_notification is sending email based on the the template my_module.email_hr_employee_notification, see this post how to create email template with xml, schedule_action is the function called by the scheduler.

import logging
import openerp.addons.decimal_precision as dp
from datetime import datetime, date, timedelta
from openerp.exceptions import UserError
from openerp import models, fields, api, _

_logger = logging.getLogger(__name__)
    
class HrEmployee(models.Model):
    _inherit = 'hr.employee'
    
    enable_send_notification = fields.Boolean(string='Send notification')

    @api.multi
    def send_notification(self):
        self.ensure_one()
        ir_model_data = self.env['ir.model.data']
        template_obj = self.env.ref('my_module.email_hr_employee_notification')
        template_obj.send_mail(self.ids[0], force_send=True)
        return True
    
    def schedule_action(self, cr, uid, context=None):
        hr_employee_obj = self.pool.get('hr.employee')
        hr_employee_ids = self.pool.get('hr.employee').search(cr, uid, [])
        for hr_employee_id in hr_employee_ids:
            hr_employee = hr_employee_obj.browse(cr, uid, hr_employee_id , context=context)
            if hr_employee.enable_send_notification:
                hr_employee.send_notification()

Whitelist / Blacklist Amavis SpamAssassin Zimbra 8.6

mail

Sometimes SpamAssassin scores email as False Positive spam, to avoid incoming emails to get junked, we can define globally in the config file /opt/zimbra/conf/amavisd.conf.in domain with a initial score.

#  read_hash("/var/amavis/sender_scores_sitewide"),

   { # a hash-type lookup table (associative array)
     'nobody@cert.org'                        => -3.0,
     'cert-advisory@us-cert.gov'              => -3.0,
     'owner-alert@iss.net'                    => -3.0,
     'slashdot@slashdot.org'                  => -3.0,
     ...

To whitelist a domain we add domain with a negative score:

#  read_hash("/var/amavis/sender_scores_sitewide"),

   { # a hash-type lookup table (associative array)
     'mydomain.com'                           => -3.0,
     'nobody@cert.org'                        => -3.0,
     'cert-advisory@us-cert.gov'              => -3.0,
     'owner-alert@iss.net'                    => -3.0,
     'slashdot@slashdot.org'                  => -3.0,
     ...

To blacklist a domain we add domain with positive score:

#  read_hash("/var/amavis/sender_scores_sitewide"),

   { # a hash-type lookup table (associative array)
     'spammer.com'                            =>  5.0,
     'nobody@cert.org'                        => -3.0,
     'cert-advisory@us-cert.gov'              => -3.0,
     'owner-alert@iss.net'                    => -3.0,
     'slashdot@slashdot.org'                  => -3.0,
     ...

To apply the modification restart Amavis:

su - zimbra
zmamavisdctl restart

Now from the source of incoming emails we can see when it’s coming from mydomain.com the initial score is -3 and spammer.com is 5.

X-Virus-Scanned: amavisd-new at mail.numberspeaks.com
X-Spam-Flag: NO
X-Spam-Score: -2
X-Spam-Level:
X-Spam-Status: No, score=-2 tagged_above=-10 required=6 tests=[AM.WBL=-3,
	BAYES_40=-0.001, HTML_MESSAGE=0.001, KAM_LAZY_DOMAIN_SECURITY=1]
	autolearn=no autolearn_force=no

Make OpenVPN stealthy with stunnel on Mac OS and Debian

openvpn stunnel

OpenVPN is more and less banned in some countries, therefore to be able to use it there, we need to make it stealthy by installing a 3rd party software like Tor, SSH Tunnel or Stunnel which hides openVPN traffic from governmental firewall detection. The principle is quite simple, we create a tunnel between our computer and the openVPN server which is encrypted by a certificate, then send our openVPN traffic through this tunnel.

Debian 8 stunnel server installation

First OpenVPN should be configured to use TCP instead of UDP, on this example we open port number 1000 and redirect the traffic to localhost port number 443 which is my openVPN server port. We will start by installing the package, run this command to install sTunnel:

apt-get install stunnel4

Follow the installation wizard and edit /etc/stunnel/stunnel.conf with your favorite editor like bellow:

# Location of the certificate that we created
cert = /etc/stunnel/stunnel.pem
client = no
output = /var/log/stunnel4/stunnel.log
# Name of the connection
[openvpn]
accept = 1000
connect = 127.0.0.1:443

If after the installation there’s no stunnel.pem file, we can create the certificate by running this following command.

openssl genrsa -out key.pem 2048
openssl req -new -x509 -key key.pem -out cert.pem -days 1095
cat key.pem cert.pem >> /etc/stunnel/stunnel.pem

Start sTunnel

service stunnel4 start

check stunnel.log to make sure there’s no error.

Mac OS X stunnel client installation and configuration

First we need to install homebrew, installation guide is on HomeBrew‘s website. After completing homebrew installation run this command:

brew install stunnel

Then edit stunnel.conf file, run this command:

vi /usr/local/etc/stunnel/stunnel.conf
pid = /usr/local/etc/stunnel/stunnel.pid
output = /usr/local/etc/stunnel/stunnel.log
[openvpn-localhost]
client = yes
accept = 127.0.0.1:1000
connect = 80.247.81.210:1000

This config file will create a tunnel from localhost on port 1000 to the remote ip 80.247.81.210 on port 1000, change the ip 80.247.81.210 and the port following your current network configuration.

Mac OS X openVPN configuration

I will not describe how to setup the openVPN client, but there’s 2 mandatory modifications to bring to our conf file. Change the remote ip address to localhost with the right port we just set before on sTunnel config file and add those new directives redirect-gateway def1 and route remote_vpn_ip_address 255.255.255.255 net_gateway that will route all internet traffic to the VPN gateway except the one in destination to our remote vpn ip address.

remote localhost 1000
redirect-gateway def1
route remote_vpn_ip_address 255.255.255.255 net_gateway

Save the modification and restart openVPN.

service openvpn restart

Start sTunnel on Mac OS X

Make sure the sTunnel server is up and running before starting stunnel on the client:

sudo stunnel

Now you can use your new openVPN config file to connect stealthy on your openVPN server.

Send an email using a template

mail

Create a function in your model:

@api.multi
def send_email_notification(self):
    self.ensure_one()
    ir_model_data = self.env['ir.model.data']
    template_obj = self.env.ref('abc.email_template')
    template_obj.send_mail(self.ids[0], force_send=True)
    return True

call the function by the following XML code:

<button name="action_email_notification" string="Send Email Notification" type="object" class="oe_highlight" />

Odoo 9 Email Template

mail
This is a basic email template to put in the xml file:

<record id="email_template" model="mail.template">
    <field name="name">My Email Template</field>
    <field name="email_from">no-reply@domain.com</field>
    <field name="subject">Email Template</field>
    <field name="partner_to">${object.address_home_id.id}</field>
    <field name="model_id" ref="module_name.model_model_name" />
    <field name="auto_delete" eval="True" />
    <field name="lang">${object.user_id.lang}</field>
    <field name="body_html"><![CDATA[<div>My email template</div>]]></field>
</record>

if the module name is abc and the model name is voyelle then module_name.model_model_name should be abc.model_voyelle.
${object} is the model ${object.name} will display the attribute name of the current model.

Fail2ban Odoo 9 Authentication

fail2ban

Odoo 9 community doesn’t come with autoban security. Fail2ban is an alternative to secure Odoo authentication. For more information concerning fail2ban click here

Let’s start with creating a new filter:

vi /etc/fail2ban/filter.d/odoo.conf

Paste the content from bellow code:

[INCLUDES]

# Read common prefixes. If any customizations available -- read them from
# common.local
before = common.conf

[Definition]

failregex = INFO:openerp.addons.base.res.res_users:Login failed for db:.* login:.*\n.*INFO:werkzeug: - - \[.*\] \"POST /web/login .*\" 200 -
         - \[.*\] \"POST /web/database/(drop|duplicate|create) HTTP/2.0\"

ignoreregex =
journalmatch = _SYSTEMD_UNIT=odoo.service + _COMM=odoo

[Init]

maxlines = 2

Add those line in jail.local

[odoo]
enabled = true
port    = 443,80,8069
filter  = odoo
logpath = /var/log/syslog
maxretry = 5
bantime  = -1
findtime = 1h

Change the value of syslog in the /etc/odoo/openerp-server.conf

syslog = True

Restart Odoo then fail2ban to apply modification.

DKIM Zimbra 8.6

DKIM is an email authentication method designed to detect email spoofing, for more detail : Wiki DKIM

Make sure your DKIM has been enabled in your zimbra.

su - zimbra
/opt/zimbra/libexec/zmdkimkeyutil -a -d domain.com
148ERADC-FCE5-11E6-AF44-005A1B26B745._domainkey	IN	TXT	( "v=DKIM1; k=rsa; "	  "p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDg2uVLIssdfsfgu62+c7n0sxugzm8Lpr4A7o7veL4kIeifat2hD53P2KKQTV978HxBTQKrEFByLbG0WZuNracNJU9L5NOKtmYnE7ksxF9ODMKqFK+ltsmM9qkVxbU3xQOVdufDlV2Zk8Ya0WMkYWzKgWIwIDAQAB" )  ; ----- DKIM key 148ERADC-FCE5-11E6-AF44-005A1B26B745 for domain.com

Add DNS TXT record:

148ERADC-FCE5-11E6-AF44-005A1B26B745._domainkey IN TXT v=DKIM1; k=rsa;p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDg2uVLIssdfsfgu62+c7n0sxugzm8Lpr4A7o7veL4kIeifat2hD53P2KKQTV978HxBTQKrEFByLbG0WZuNracNJU9L5NOKtmYnE7ksxF9ODMKqFK+ltsmM9qkVxbU3xQOVdufDlV2Zk8Ya0WMkYWzKgWIwIDAQAB

Test DKIM signature by sending email using this website: http://dkimvalidator.com/

DKIM Validator

Protect Jasper PDF report by a password

Protected PDF

To do so, just add in the xml file of your report those following lines

<property name="net.sf.jasperreports.export.pdf.encrypted" value="True"/>
<property name="net.sf.jasperreports.export.pdf.128.bit.key" value="True"/>
<property name="net.sf.jasperreports.export.pdf.user.password" value="mySuperPass"/>
<property name="net.sf.jasperreports.export.pdf.owner.password" value="mySuperPass"/>

JasperServer Community 6.0.1
Jaspersoft Studio 6.0.1