Skip to content

Commit

Permalink
add desktop certificat
Browse files Browse the repository at this point in the history
  • Loading branch information
Kev-Roche committed May 27, 2024
1 parent 07f034c commit fdbe30c
Show file tree
Hide file tree
Showing 19 changed files with 1,138 additions and 0 deletions.
70 changes: 70 additions & 0 deletions desktop_certificate/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
===================
Desktop Certificats
===================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:2bffd83f3e44d4fff1cab3eca36cc7170c1008fed1bf1fea9222d041e920e331
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-akretion%2Fak--odoo--incubator-lightgray.png?logo=github
:target: https://github.com/akretion/ak-odoo-incubator/tree/14.0/desktop_certificate
:alt: akretion/ak-odoo-incubator

|badge1| |badge2| |badge3|

This module allows to manage certificates TLS / MPKI / SSL.
It manages the creation and renewal of certificates and the installation of the certificates on your server.
It allows you to manage your certificates in a simple and efficient way.

**Table of contents**

.. contents::
:local:

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/akretion/ak-odoo-incubator/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/akretion/ak-odoo-incubator/issues/new?body=module:%20desktop_certificate%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
~~~~~~~

* Akretion

Contributors
~~~~~~~~~~~~

* Kévin Roche <[email protected]>

Maintainers
~~~~~~~~~~~

.. |maintainer-Kev-Roche| image:: https://github.com/Kev-Roche.png?size=40px
:target: https://github.com/Kev-Roche
:alt: Kev-Roche

Current maintainer:

|maintainer-Kev-Roche|

This module is part of the `akretion/ak-odoo-incubator <https://github.com/akretion/ak-odoo-incubator/tree/14.0/desktop_certificate>`_ project on GitHub.

You are welcome to contribute.
1 change: 1 addition & 0 deletions desktop_certificate/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
28 changes: 28 additions & 0 deletions desktop_certificate/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright 2024 Akretion (https://www.akretion.com).
# @author Kévin Roche <[email protected]>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

{
"name": "Desktop Certificats",
"summary": "Generate and manage TSL certificates of users",
"version": "14.0.1.0.0",
"category": "tools",
"website": "https://github.com/akretion/ak-odoo-incubator",
"author": "Akretion, Odoo Community Association (OCA)",
"license": "AGPL-3",
"maintainers": ["Kev-Roche"],
"application": False,
"installable": True,
"depends": [
"stock",
"mail",
],
"data": [
"data/data.xml",
"security/res_groups.xml",
"security/ir.model.access.csv",
"security/rule.xml",
"views/desktop.xml",
"views/desktop_certificate.xml",
],
}
56 changes: 56 additions & 0 deletions desktop_certificate/data/data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo noupdate="1">
<record id="mpki_api_url" model="ir.config_parameter">
<field name="key">mpki_api_url</field>
<field name="value">http://front.home.arpa:8096/certs</field>
</record>
<record id="mpki_api_user" model="ir.config_parameter">
<field name="key">mpki_api_user</field>
<field name="value"></field>
</record>
<record id="mpki_api_password" model="ir.config_parameter">
<field name="key">mpki_api_password</field>
<field name="value" />
</record>

<record id="ir_cron_send_email_certificate_expiration" model="ir.cron">
<field
name="name"
>Email d'alerte d'expiration de certificats informatique.</field>
<field name="active" eval="True" />
<field name="user_id" ref="base.user_root" />
<field name="interval_number">3</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field name="model_id" ref="model_desktop" />
<field name="code">model.cron_send_email_certificate_expiration()</field>
</record>
<record id="mail_certificate_expiration" model="mail.template">
<field
name="name"
>Email d'alerte d'expiration de certificats informatique</field>
<field name="model_id" ref="model_desktop" />
<field name="subject">Certificats à renouveler sous 15 jours</field>
<field name="email_to" />
<field name="body_html" type="xml">
<div style="margin: 0px; padding: 0px;">
<p style="margin: 0px; padding: 0px; font-size: 13px;">
--- MAIL AUTOMATIQUE ---<br /><br />
Bonjour,<br /><br />
Voici la liste des certificats qui expireront sous 15 jours:
<br />
<ul>
% for line in object.env.context.get('certifs_ids'):
<li><b>${line.name}</b> : ${line.expiration_date}</li>
% endfor
</ul>

<br />
Cordialement
</p>
</div>
</field>
<field name="report_name">${(object.name or '').replace('/','-')}</field>
<field name="auto_delete" eval="True" />
</record>
</odoo>
3 changes: 3 additions & 0 deletions desktop_certificate/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from . import desktop_certificate

from . import desktop
190 changes: 190 additions & 0 deletions desktop_certificate/models/desktop.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
# Copyright 2024 Akretion (https://www.akretion.com).
# @author Kévin Roche <[email protected]>

import json
from datetime import datetime

import requests

from odoo import _, api, fields, models
from odoo.exceptions import UserError


class Desktop(models.Model):
_name = "desktop"
_inherit = ["mail.thread"]
_description = "Desktop"

name = fields.Char(string="Nom")
location_id = fields.Many2one(
comodel_name="stock.warehouse", string="Lieu", required=True
)
company_id = fields.Many2one(
comodel_name="res.company",
string="Société",
default=lambda self: self.env.company,
)
certificate_partner_id = fields.Many2one(
comodel_name="res.partner",
string="Certificats envoyés à",
domain=[("user_ids", "!=", False)],
default=lambda self: self.env.user.partner_id,
)
certificate_email = fields.Char(
string="Certificat envoyé à", related="certificate_partner_id.email"
)
certificate_phone = fields.Char(
string="Mot de passe du certificat envoyé à",
related="certificate_partner_id.mobile",
)

certificate_ids = fields.One2many(
comodel_name="desktop.certificate",
inverse_name="desktop_id",
string="Certificats",
)
certificate_state = fields.Selection(
selection=[
("1_short", "< 15 jours"),
("2_medium", "< 3 mois"),
("3_long", "> 3 mois"),
("4_revoked", "Révoqué"),
("5_obsolete", "Obsolète"),
("none", "Aucun certificat"),
],
string="Etat Certificats",
compute="_compute_valid_certificate_state",
store=True,
)

certificate_min_exp_date = fields.Date(
string="Date d'expiration",
compute="_compute_certificate_min_exp_date",
)

valid_certificate_count = fields.Integer(
compute="_compute_valid_certificate_count", string="Certificats Valides"
)

def _compute_certificate_min_exp_date(self):
for rec in self:
rec.certificate_min_exp_date = None
certifs = rec.certificate_ids
if certifs:
current_datetime = datetime.now()
valid_datetime_list = [
certif.expiration_date
for certif in certifs
if certif.expiration_date >= current_datetime
and not certif.revoked
and certif.active
]
if valid_datetime_list:
rec.certificate_min_exp_date = max(valid_datetime_list).date()

def _compute_valid_certificate_state(self):
for rec in self:
certif_states = rec.certificate_ids.mapped("state")
if certif_states:
if "short" in certif_states:
rec.certificate_state = "1_short"
elif "medium" in certif_states:
rec.certificate_state = "2_medium"
elif "long" in certif_states:
rec.certificate_state = "3_long"
elif "revoked" in certif_states:
rec.certificate_state = "4_revoked"
else:
rec.certificate_state = "5_obsolete"
else:
rec.certificate_state = "none"

def cron_send_email_certificate_expiration(self):
certifs = self.env["maintenance.certificate"].search([])
certifs._compute_valid_certificate_state()
short_certifs = certifs.filtered(lambda x: x.state == "short")
if short_certifs:
email_template = self.env.ref("infra.mail_certificate_expiration")
self.with_context(
certifs_ids=short_certifs.equipment_id
).message_post_with_template(email_template.id)

@api.depends("certificate_ids")
def _compute_valid_certificate_count(self):
for record in self:
record.valid_certificate_count = len(
record.certificate_ids.filtered(
lambda c: not c.revoked and c.expiration_date > datetime.now()
)
)

def _get_mpki_api(self):
ir_config_model = self.env["ir.config_parameter"].sudo()
mpki_api = {}
mpki_api["url"] = ir_config_model.get_param("mpki_api_url")
mpki_api["user"] = ir_config_model.get_param("mpki_api_user")
mpki_api["password"] = ir_config_model.get_param("mpki_api_password")
return mpki_api

def generate_certificate(self):
mpki_api = self._get_mpki_api()
for record in self:
partner = record.certificate_partner_id
if not partner.email:
raise UserError(_("L'email du destinataire est vide"))
if not partner.mobile:
raise UserError(_("Le mobile du destinataire est vide"))
location = record.location_id.partner_id
params = {
"certificate": {
"name": record.name,
},
"partner": {
"name": partner.display_name,
"phone": partner.mobile,
"email": partner.email,
},
"location": {
"name": location.name,
"company": location.company_id.name,
"city": location.city,
"zipcode": location.zip,
"country": location.country_id.name,
},
}
res = requests.post(
mpki_api["url"],
auth=(mpki_api["user"], mpki_api["password"]),
json=params,
)
if res.status_code == requests.codes.ok:
res_dict = res.json()
self.env["desktop.certificate"].create(
{
"revoked": not res_dict["valid"],
"name": res_dict["name"],
"expiration_date": datetime.fromisoformat(
res_dict["valid_until"]
),
"desktop_id": record.id,
"sent_to_email": record.certificate_email,
"sent_to_phone": record.certificate_phone,
}
)
else:
try:
raise UserError(json.dumps(res.json(), indent=4))
except ValueError:
raise UserError(res.text)
return None

@api.onchange("location_id")
def _onchange_location(self):
if self.location_id:
self.company_id = self.location_id.company_id.id or False

def unlink(self):
desktops = self.mapped("desktop_id")
super().unlink()
desktops.unlink()
return True
Loading

0 comments on commit fdbe30c

Please sign in to comment.