[Python] How to restrict user login in Odoo based on time range

Discussão em 'Python' iniciado por Stack, Maio 11, 2025.

  1. Stack

    Stack Membro Participativo

    I'm building a custom Odoo module that should allow users to log in only during specific hours (e.g., between 08:00 and 18:00). I added access_start_time and access_end_time as fields.Float, and I overrode the _check_credentials() method in res.users.

    Here’s the logic I'm using:

    from datetime import datetime
    from odoo import models, fields, api, _
    from odoo.exceptions import ValidationError, AccessDenied


    class ResUsers(models.Model):
    _inherit = 'res.users'

    access_start_time = fields.Float(
    string="Heure de début d'accès", default=8.0,
    help="Heure au format 24h, exemple: 8.5 pour 08:30"
    )
    access_end_time = fields.Float(
    string="Heure de fin d'accès", default=18.0,
    help="Heure au format 24h, exemple: 18.0 pour 18:00"
    )

    @api.constrains('access_start_time', 'access_end_time')
    def _check_valid_time_range(self):
    for rec in self:
    if not (0 <= rec.access_start_time <= 23.99):
    raise ValidationError(_("L'heure de début doit être comprise entre 00:00 et 23:59."))
    if not (0 <= rec.access_end_time <= 23.99):
    raise ValidationError(_("L'heure de fin doit être comprise entre 00:00 et 23:59."))
    if rec.access_start_time >= rec.access_end_time:
    raise ValidationError(_("L'heure de début doit être inférieure à l'heure de fin."))

    def _check_credentials(self, password):
    """Override to restrict login based on time."""
    super()._check_credentials(password)

    now = datetime.now().time()
    current_hour = now.hour + now.minute / 60

    if not self._uid:
    return

    user = self.browse(self._uid)
    if not user.exists() or user._is_admin():
    return # Don't block admin or invalid users

    start = user.access_start_time or 0.0
    end = user.access_end_time or 23.99

    if not (start <= current_hour <= end):
    raise AccessDenied(_(
    "⛔ Accès refusé ! Vos horaires autorisés sont de %s à %s."
    ) % (
    f"{int(start):02d}:{int((start % 1) * 60):02d}",
    f"{int(end):02d}:{int((end % 1) * 60):02d}",
    ))


    i also tried with controllers :

    from odoo import http, _
    from odoo.http import request
    from datetime import datetime
    from odoo.exceptions import AccessDenied

    class AuthControllerOverride(http.Controller):

    @http.route('/web/login', type='http', auth="none")
    def web_login(self, redirect=None, **kw):
    response = request.redirect_with_hash('/web')
    if request.httprequest.method == 'POST':
    uid = request.session.authenticate(
    request.session.db, kw['login'], kw['password']
    )
    user = request.env['res.users'].sudo().browse(uid)
    if not user._is_admin():
    now = datetime.now().time()
    current_hour = now.hour + now.minute / 60
    start = user.access_start_time or 0.0
    end = user.access_end_time or 23.99

    if not (start <= current_hour <= end):
    # Kill session and show error
    request.session.logout()
    return request.render('web.login', {
    'error': _("⛔ Accès refusé : vous êtes hors de vos horaires autorisés (%s - %s).") % (
    f"{int(start):02d}:{int((start % 1) * 60):02d}",
    f"{int(end):02d}:{int((end % 1) * 60):02d}",
    )
    })
    return response


    but always same proble, the user can login like the condition doesn't exist. please how to do it

    Continue reading...

Compartilhe esta Página