-
-
Notifications
You must be signed in to change notification settings - Fork 119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[16.0][ADD] hr_attendance_ip_check: IP-based attendance validation #189
base: 16.0
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
========================= | ||
IP-based Attendance Check | ||
========================= | ||
|
||
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
!! This file is generated by oca-gen-addon-readme !! | ||
!! changes will be overwritten. !! | ||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
|
||
.. |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-OCA%2Fhr-lightgray.png?logo=github | ||
:target: https://github.com/OCA/hr/tree/16.0/hr_attendance_ip_check | ||
:alt: OCA/hr | ||
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png | ||
:target: https://translation.odoo-community.org/projects/hr-16-0/hr-16-0-hr_attendance_ip_check | ||
:alt: Translate me on Weblate | ||
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png | ||
:target: https://runbot.odoo-community.org/runbot/hr/16.0 | ||
:alt: Try me on Runbot | ||
|
||
|badge1| |badge2| |badge3| |badge4| |badge5| | ||
|
||
This module extends the HR Attendance module to add IP-based validation for attendance check-in/check-out operations. | ||
It allows companies to restrict attendance registrations to specific IP addresses or ranges, ensuring that | ||
employees can only record their attendance when they are physically present in the company network. | ||
|
||
**Table of contents** | ||
|
||
.. contents:: | ||
:local: | ||
|
||
Configuration | ||
============ | ||
|
||
To configure this module, you need to: | ||
|
||
* Go to Settings -> Human Resources -> Attendance | ||
* Enable IP-based attendance check | ||
* Enter the allowed IP addresses in the whitelist field (comma-separated) | ||
|
||
Usage | ||
===== | ||
|
||
To use this module, you need to: | ||
|
||
* Employees attempt to check in/out as normal through the Attendance interface | ||
* If IP checking is enabled: | ||
* If the employee's IP is in the whitelist, check-in/check-out proceeds normally | ||
* If the employee's IP is not in the whitelist, a red message appears under the button | ||
and the check-in/check-out operation is blocked | ||
|
||
Bug Tracker | ||
========== | ||
|
||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/hr/issues>`_. | ||
In case of trouble, please check there if your issue has already been reported. | ||
If you spotted it first, help us smashing it by providing a detailed and welcomed | ||
`feedback <https://github.com/OCA/hr/issues/new?body=module:%20hr_attendance_ip_check%0Aversion:%2016.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 | ||
~~~~~~~ | ||
|
||
* ADITI | ||
|
||
Contributors | ||
~~~~~~~~~~~~ | ||
|
||
* Kongkea Ouch <[email protected]> | ||
|
||
Maintainers | ||
~~~~~~~~~~ | ||
|
||
This module is maintained by the OCA. | ||
|
||
.. image:: https://odoo-community.org/logo.png | ||
:alt: Odoo Community Association | ||
:target: https://odoo-community.org | ||
|
||
OCA, or the Odoo Community Association, is a nonprofit organization whose | ||
mission is to support the collaborative development of Odoo features and | ||
promote its widespread use. | ||
|
||
This module is part of the `OCA/hr <https://github.com/OCA/hr/tree/16.0/hr_attendance_ip_check>`_ project on GitHub. | ||
|
||
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
"""IP-based Attendance Check module initialization.""" | ||
from . import models |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
'name': 'HR Attendance IP Check', | ||
'version': '16.0.1.0.0', | ||
'category': 'Human Resources', | ||
'summary': 'Restrict attendance check-in/check-out based on IP address', | ||
'author': 'ADITI, ' | ||
'Odoo Community Association (OCA)', | ||
'website': 'https://github.com/OCA/hr', | ||
'license': 'AGPL-3', | ||
'depends': ['hr_attendance'], | ||
'data': [ | ||
'views/res_config_settings_views.xml', | ||
] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from . import hr_employee | ||
from . import hr_attendance | ||
from . import res_config_settings |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import logging | ||
from odoo import models, api, _ | ||
|
||
_logger = logging.getLogger(__name__) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove unused imports |
||
|
||
|
||
class HrAttendance(models.Model): | ||
_inherit = 'hr.attendance' | ||
|
||
@api.model_create_multi | ||
def create(self, vals_list): | ||
"""Override create to validate IP before creating attendance records.""" | ||
if not vals_list: | ||
return {'warning': _('No valid attendance records to create')} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need to return warning for missing vals_list , it would be there. Anyways warning cannot be used here like this |
||
|
||
valid_vals = [] | ||
for vals in vals_list: | ||
employee = self.env['hr.employee'].browse(vals.get('employee_id')) | ||
validation_result = employee._validate_ip_address('check_in') | ||
|
||
if isinstance(validation_result, dict): | ||
return validation_result | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Warnings cannot be returned from create functions its only used for onchange functions. Instead of warnings throw ValidationError directly from _validate_ip_address function |
||
valid_vals.append(vals) | ||
|
||
return super().create(valid_vals) | ||
|
||
def write(self, vals): | ||
"""Override write to validate IP before updating attendance records.""" | ||
if 'check_out' in vals: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check for both check in and check out as check in time can also be modified later and accordingly pass check_in/check_out on line 31 |
||
for attendance in self: | ||
validation_result = attendance.employee_id._validate_ip_address('check_out') | ||
if isinstance(validation_result, dict): | ||
return validation_result | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similarly to create functions, warnings cannot be returned |
||
|
||
return super().write(vals) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import logging | ||
from odoo import models, _ | ||
from odoo.http import request | ||
from werkzeug.exceptions import HTTPException | ||
|
||
_logger = logging.getLogger(__name__) | ||
|
||
|
||
class HrEmployee(models.Model): | ||
_inherit = 'hr.employee' | ||
|
||
def _get_current_ip(self): | ||
"""Get the current IP address from the request.""" | ||
try: | ||
if request and request.httprequest: | ||
return request.httprequest.remote_addr | ||
except (AttributeError, HTTPException) as e: | ||
_logger.error("Error getting IP address: %s", str(e), exc_info=True) | ||
return None | ||
|
||
def _validate_ip_address(self, action_type='attendance'): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. return validation errors instead of warnings in this function |
||
"""Validate if current IP is allowed for attendance actions.""" | ||
if not self.env['ir.config_parameter'].sudo().get_param( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make use of const_eval(after importing it) const_eval(self.env['ir.config_parameter'].sudo().get_param('hr_attendance.ip_check_enabled', 'False'))) |
||
'hr_attendance.ip_check_enabled', 'False').lower() == 'true': | ||
return True | ||
|
||
current_ip = self._get_current_ip() | ||
if not current_ip: | ||
return { | ||
'warning': _('Unable to determine your IP address') | ||
} | ||
|
||
whitelist_ips = [ | ||
ip.strip() | ||
for ip in self.env['ir.config_parameter'].sudo() | ||
.get_param('hr_attendance.whitelist_ips', '').split(',') | ||
if ip.strip() | ||
] | ||
|
||
if not whitelist_ips: | ||
return { | ||
'warning': _('No IP addresses are whitelisted') | ||
} | ||
|
||
if current_ip not in whitelist_ips: | ||
return { | ||
'warning': _('You are not allowed to %(action)s from current IP address (%(ip)s)') % { | ||
'action': action_type.replace('_', ' '), | ||
'ip': current_ip | ||
} | ||
} | ||
|
||
return True | ||
|
||
def attendance_manual(self, next_action, entered_pin=None): | ||
"""Handle manual attendance with IP validation.""" | ||
self.ensure_one() | ||
|
||
# Determine action type based on current state | ||
action_type = 'check_out' if self.attendance_state == 'checked_in' else 'check_in' | ||
|
||
# Validate IP first | ||
ip_validation = self._validate_ip_address(action_type) | ||
if isinstance(ip_validation, dict): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Validation error should be raised so no need to checking if its a dictionary |
||
return ip_validation | ||
|
||
# Let hr_attendance handle the rest (PIN check, etc) | ||
return super().attendance_manual(next_action, entered_pin) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
from odoo import fields, models | ||
|
||
class ResConfigSettings(models.TransientModel): | ||
_inherit = 'res.config.settings' | ||
|
||
ip_check_enabled = fields.Boolean( | ||
string='Enable IP-based Attendance Check', | ||
config_parameter='hr_attendance.ip_check_enabled', | ||
help="Enable IP address validation for attendance check-in/check-out" | ||
) | ||
whitelist_ips = fields.Char( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of having a comma separated list of IPs which would be very difficult to handle in long run, some other way should be used to handle the IPs.For ex: The allowed IPs can be stored on a per employee basis |
||
string='Whitelist IP Addresses', | ||
config_parameter='hr_attendance.whitelist_ips', | ||
help="Comma-separated list of allowed IP addresses") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
Configuration | ||
============ | ||
|
||
To configure IP-based attendance checking: | ||
|
||
1. Go to Settings -> Human Resources -> Attendance | ||
2. Enable IP-based attendance check | ||
3. Enter the allowed IP addresses in the whitelist field (comma-separated) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
Contributors | ||
=========== | ||
|
||
* Kongkea Ouch <[email protected]> | ||
|
||
Maintainers | ||
---------- | ||
|
||
This module is maintained by the OCA. | ||
|
||
.. image:: https://odoo-community.org/logo.png | ||
:alt: Odoo Community Association | ||
:target: https://odoo-community.org | ||
|
||
OCA, or the Odoo Community Association, is a nonprofit organization whose | ||
mission is to support the collaborative development of Odoo features and | ||
promote its widespread use. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
========================== | ||
IP-based Attendance Check | ||
========================== | ||
|
||
This module extends the HR Attendance module to add IP-based validation for attendance check-in/check-out operations. | ||
It allows companies to restrict attendance registrations to specific IP addresses or ranges, ensuring that | ||
employees can only record their attendance when they are physically present in the company network. | ||
|
||
Key features: | ||
------------ | ||
* IP whitelist configuration for attendance check-in/check-out | ||
* Easy enable/disable of IP verification | ||
* Visual feedback when attempting check-in/check-out from unauthorized IP | ||
* Flexible configuration through settings menu |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
Development | ||
========== | ||
|
||
To modify this module, you will need to: | ||
|
||
1. Clone the OCA HR repository | ||
2. Create a new branch | ||
3. Install development dependencies: | ||
* No special dependencies required beyond Odoo dependencies | ||
|
||
Bug Tracker | ||
---------- | ||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/hr/issues>`_. | ||
In case of trouble, please check there if your issue has already been reported. | ||
If you spotted it first, help us smashing it by providing a detailed and welcomed | ||
feedback. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
Usage | ||
===== | ||
|
||
Regular Usage | ||
------------ | ||
1. Employees attempt to check in/out as normal through the Attendance interface | ||
2. If IP checking is enabled: | ||
* If the employee's IP is in the whitelist, check-in/check-out proceeds normally | ||
* If the employee's IP is not in the whitelist, a warning message appears | ||
and the check-in/check-out operation is blocked | ||
|
||
Administrator Usage | ||
----------------- | ||
1. Go to Settings -> Human Resources -> Attendance | ||
2. Enable or disable IP-based attendance check | ||
3. Configure the whitelist of allowed IP addresses | ||
|
||
Troubleshooting | ||
------------- | ||
* If an employee cannot check in/out: | ||
- Verify their IP address | ||
- Check if the IP is in the whitelist | ||
- Verify that IP checking is enabled |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# No additional requirements beyond Odoo |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import test_hr_attendance |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for this comment