mirror of
https://github.com/bringout/oca-server-auth.git
synced 2026-04-18 13:52:04 +02:00
82 lines
2.8 KiB
Python
82 lines
2.8 KiB
Python
# © 2021 Florian Kantelberg - initOS GmbH
|
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
|
|
import logging
|
|
import re
|
|
from hashlib import sha256
|
|
from uuid import uuid4
|
|
|
|
from odoo import _, api, fields, models
|
|
from odoo.exceptions import ValidationError
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class ResUsersKey(models.Model):
|
|
_name = "res.users.key"
|
|
_description = _("User data of a vault")
|
|
_rec_name = "fingerprint"
|
|
_order = "create_date DESC"
|
|
|
|
user_id = fields.Many2one("res.users", required=True)
|
|
uuid = fields.Char(default=lambda self: uuid4(), required=True, readonly=True)
|
|
current = fields.Boolean(default=True, readonly=True)
|
|
fingerprint = fields.Char(compute="_compute_fingerprint", store=True)
|
|
public = fields.Char(required=True, readonly=True)
|
|
salt = fields.Char(required=True, readonly=True)
|
|
iv = fields.Char(required=True, readonly=True)
|
|
iterations = fields.Integer(required=True, readonly=True)
|
|
version = fields.Integer(readonly=True)
|
|
# Encrypted with master password of user
|
|
private = fields.Char(required=True, readonly=True)
|
|
|
|
@api.depends("public")
|
|
def _compute_fingerprint(self):
|
|
for rec in self:
|
|
if rec.public:
|
|
hashed = sha256(rec.public.encode()).hexdigest()
|
|
rec.fingerprint = ":".join(re.findall(r".{2}", hashed))
|
|
else:
|
|
rec.fingerprint = False
|
|
|
|
def _prepare_values(self, iterations, iv, private, public, salt, version):
|
|
return {
|
|
"iterations": iterations,
|
|
"iv": iv,
|
|
"private": private,
|
|
"public": public,
|
|
"salt": salt,
|
|
"user_id": self.env.uid,
|
|
"current": True,
|
|
"version": version,
|
|
}
|
|
|
|
def store(self, iterations, iv, private, public, salt, version):
|
|
if not all(isinstance(x, str) and x for x in [public, private, iv, salt]):
|
|
raise ValidationError(_("Invalid parameter"))
|
|
|
|
if not isinstance(iterations, int) or iterations < 4000:
|
|
raise ValidationError(_("Invalid parameter"))
|
|
|
|
if not isinstance(version, int):
|
|
raise ValidationError(_("Invalid parameter"))
|
|
|
|
domain = [
|
|
("user_id", "=", self.env.uid),
|
|
("private", "=", private),
|
|
]
|
|
key = self.search(domain)
|
|
if not key:
|
|
# Disable all current keys
|
|
self.env.user.keys.write({"current": False})
|
|
|
|
rec = self.create(
|
|
self._prepare_values(iterations, iv, private, public, salt, version)
|
|
)
|
|
return rec.uuid
|
|
|
|
return False
|
|
|
|
def extract_public_key(self, user):
|
|
user = self.sudo().search([("user_id", "=", user), ("current", "=", True)])
|
|
return user.public or None
|