@ -0,0 +1,50 @@ |
|||
.. image:: https://img.shields.io/badge/licence-LGPL--3-green.svg |
|||
:target: https://www.gnu.org/licenses/lgpl-3.0-standalone.html |
|||
:alt: License: LGPL-3 |
|||
|
|||
Unauthorized Login Notification And Image Capture |
|||
================================================= |
|||
This module automatically captures an image when an incorrect password is entered during login and sends a notification. |
|||
|
|||
Configuration |
|||
============= |
|||
openCv must be installed (pip install opencv-python) |
|||
|
|||
Company |
|||
------- |
|||
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__ |
|||
|
|||
License |
|||
------- |
|||
General Public License, Version 3 (LGPL v3). |
|||
(https://www.gnu.org/licenses/lgpl-3.0-standalone.html) |
|||
|
|||
Credits |
|||
------- |
|||
Developer: (V18) Unnimaya CO, |
|||
(V17) Afra MP, |
|||
(V16) Fathima Mazlin AM |
|||
|
|||
Contact: odoo@cybrosys.com |
|||
|
|||
Contacts |
|||
-------- |
|||
* Mail Contact : odoo@cybrosys.com |
|||
* Website : https://cybrosys.com |
|||
|
|||
Bug Tracker |
|||
----------- |
|||
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. |
|||
|
|||
Maintainer |
|||
========== |
|||
.. image:: https://cybrosys.com/images/logo.png |
|||
:target: https://cybrosys.com |
|||
|
|||
This module is maintained by Cybrosys Technologies. |
|||
|
|||
For support and more information, please visit `Our Website <https://cybrosys.com/>`__ |
|||
|
|||
Further information |
|||
=================== |
|||
HTML Description: `<static/description/index.html>`__ |
@ -0,0 +1,23 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
|||
# Author: Unnimaya CO (odoo@cybrosys.com) |
|||
# |
|||
# This program is free software: you can modify |
|||
# it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE (LGPL) as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU LESSER GENERAL PUBLIC LICENSE for more details. |
|||
# |
|||
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
|||
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
from . import controllers |
|||
from . import models |
@ -0,0 +1,49 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
|||
# Author: Unnimaya CO (odoo@cybrosys.com) |
|||
# |
|||
# This program is free software: you can modify |
|||
# it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE (LGPL) as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU LESSER GENERAL PUBLIC LICENSE for more details. |
|||
# |
|||
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
|||
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
{ |
|||
'name': 'Unauthorized Login Notification And Image Capture', |
|||
'version': '18.0.1.0.0', |
|||
'category': 'Extra Tools', |
|||
'summary': """Automatic image capture while login with wrong password and a |
|||
notification is sent.""", |
|||
'description': """This module helps you to Automatic image capture while |
|||
login with wrong password and a notification is sent. And also stored the |
|||
details of unauthorised access in backend""", |
|||
'author': 'Cybrosys Techno Solutions', |
|||
'company': 'Cybrosys Techno Solutions', |
|||
'maintainer': 'Cybrosys Techno Solutions', |
|||
'website': 'https://www.cybrosys.com', |
|||
'depends': ['mail'], |
|||
'data': [ |
|||
'security/ir.model.access.csv', |
|||
'data/mail_data.xml', |
|||
'views/auto_capture_views.xml', |
|||
], |
|||
'external_dependencies': { |
|||
'python': ['cv2'] |
|||
}, |
|||
'images': ['static/description/banner.jpg'], |
|||
'license': 'LGPL-3', |
|||
'installable': True, |
|||
'auto_install': False, |
|||
'application': True, |
|||
} |
@ -0,0 +1,22 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
|||
# Author: Unnimaya CO (odoo@cybrosys.com) |
|||
# |
|||
# This program is free software: you can modify |
|||
# it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE (LGPL) as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU LESSER GENERAL PUBLIC LICENSE for more details. |
|||
# |
|||
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
|||
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
from . import detect_unauthorized_login |
@ -0,0 +1,137 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
|||
# Author: Unnimaya CO (odoo@cybrosys.com) |
|||
# |
|||
# This program is free software: you can modify |
|||
# it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE (LGPL) as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU LESSER GENERAL PUBLIC LICENSE for more details. |
|||
# |
|||
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
|||
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
import base64 |
|||
import cv2 |
|||
import datetime |
|||
import logging |
|||
import odoo |
|||
import odoo.modules.registry |
|||
from odoo import http |
|||
from odoo.http import request |
|||
from odoo.tools.translate import _ |
|||
from odoo.addons.web.controllers.home import Home |
|||
|
|||
_logger = logging.getLogger(__name__) |
|||
# Shared parameters for all login/signup flows |
|||
SIGN_UP_REQUEST_PARAMS = {'db', 'login', 'debug', 'token', 'message', 'error', |
|||
'scope', 'mode', 'redirect', 'redirect_hostname', |
|||
'email', 'name', 'partner_id', 'password', |
|||
'confirm_password', 'city', 'country_id', 'lang', |
|||
'signup_email'} |
|||
LOGIN_SUCCESSFUL_PARAMS = set() |
|||
|
|||
|
|||
class WrongPassword(Home): |
|||
"""While entering wrong password create an error and send mail to the user and also capture the image of |
|||
unauthorized user""" |
|||
|
|||
@http.route('/web/login', type='http', auth="none") |
|||
def web_login(self, redirect=None, **kw): |
|||
"""While entering wrong password an error message is created, |
|||
capture the image of user, and send a notification |
|||
to authorized user""" |
|||
request.params['login_success'] = False |
|||
if request.httprequest.method == 'GET' and redirect and request.session.uid: |
|||
return request.redirect(redirect) |
|||
# simulate hybrid auth=user/auth=public, despite using auth=none to |
|||
# be able to redirect users when no db is selected - cfr ensure_db() |
|||
if request.env.uid is None: |
|||
if request.session.uid is None: |
|||
# no user -> auth=public with specific website public user |
|||
request.env["ir.http"]._auth_method_public() |
|||
else: |
|||
request.update_env(user=request.session.uid) |
|||
values = {key: value for key, value in request.params.items() |
|||
if key in SIGN_UP_REQUEST_PARAMS} |
|||
try: |
|||
values['databases'] = http.db_list() |
|||
except odoo.exceptions.AccessDenied: |
|||
values['databases'] = None |
|||
if request.httprequest.method == 'POST': |
|||
try: |
|||
uid = request.session.authenticate(request.db, |
|||
{'login': request.params[ |
|||
'login'], |
|||
'password': request.params[ |
|||
'password'], |
|||
'type': 'password'}) |
|||
request.params['login_success'] = True |
|||
return request.redirect(self._login_redirect(uid, |
|||
redirect=redirect)) |
|||
except odoo.exceptions.AccessDenied as e: |
|||
if e.args == odoo.exceptions.AccessDenied().args: |
|||
values['error'] = _("Wrong login/password") |
|||
try: |
|||
# Capture an image |
|||
cap = cv2.VideoCapture(0) |
|||
ret, frame = cap.read() |
|||
ret, jpeg_image = cv2.imencode('.jpg', frame) |
|||
base64_image = base64.b64encode(jpeg_image) |
|||
cap.release() |
|||
except: |
|||
capture = request.env['auto.capture'].sudo().create({ |
|||
'email': request.params['login'], |
|||
'date': datetime.datetime.now(), |
|||
}) |
|||
User = request.env['res.users'] |
|||
user_sudo = User.sudo().search( |
|||
User._get_login_domain(request.params['login']), |
|||
order=User._get_login_order(), limit=1 |
|||
) |
|||
template = request.env.ref( |
|||
'detect_unauthorized_login' |
|||
'.mail_template_cant_access_camera').with_context( |
|||
user=user_sudo.name) |
|||
template.sudo().send_mail(capture.id, force_send=True) |
|||
else: |
|||
capture = request.env['auto.capture'].sudo().create({ |
|||
'email': request.params['login'], |
|||
'date': datetime.datetime.now(), |
|||
'image': base64_image, |
|||
}) |
|||
user_sudo = request.env['res.users'].sudo().search( |
|||
request.env['res.users']._get_login_domain( |
|||
request.params['login']), |
|||
order=request.env['res.users']._get_login_order(), |
|||
limit=1 |
|||
) |
|||
template = request.env.ref( |
|||
'detect_unauthorized_login' |
|||
'.mail_template_wrong_password').with_context( |
|||
user=user_sudo.name) |
|||
template.sudo().send_mail(capture.id, force_send=True) |
|||
else: |
|||
values['error'] = e.args[0] |
|||
else: |
|||
if 'error' in request.params and request.params.get( |
|||
'error') == 'access': |
|||
values['error'] = _( |
|||
'Only employees can access this database. ' |
|||
'Please contact the administrator.') |
|||
if 'login' not in values and request.session.get('auth_login'): |
|||
values['login'] = request.session.get('auth_login') |
|||
if not odoo.tools.config['list_db']: |
|||
values['disable_database_manager'] = True |
|||
response = request.render('web.login', values) |
|||
response.headers['X-Frame-Options'] = 'SAMEORIGIN' |
|||
response.headers['Content-Security-Policy'] = "frame-ancestors 'self'" |
|||
return response |
@ -0,0 +1,59 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<odoo> |
|||
<data noupdate="1"> |
|||
<!--Mail send while unauthorized access detected--> |
|||
<record id="mail_template_wrong_password" model="mail.template"> |
|||
<field name="name">Detect Unauthorized Login: |
|||
Suspicious sign in |
|||
</field> |
|||
<field name="model_id" |
|||
ref="detect_unauthorized_login.model_auto_capture"/> |
|||
<field name="email_from">{{user.company_id.email}}</field> |
|||
<field name="email_to">{{object.email}}</field> |
|||
<field name="subject">Password Incorrect</field> |
|||
<field name="body_html" type="html"> |
|||
<div style="margin: 0px; padding: 0px;"> |
|||
<p> |
|||
Dear <t t-out="ctx.get('user')"/>, |
|||
<br/> |
|||
<br/> |
|||
Suspicious sign in attempt to your odoo portal was |
|||
detected. |
|||
<br/> |
|||
</p> |
|||
Regards, |
|||
<br/> |
|||
<t t-out="user.company_id.name"/> |
|||
</div> |
|||
</field> |
|||
</record> |
|||
<!--Mail send while unauthorized access detected and also access denied |
|||
for camera--> |
|||
<record id="mail_template_cant_access_camera" model="mail.template"> |
|||
<field name="name">Detect Unauthorized Login: |
|||
Suspicious sign in |
|||
</field> |
|||
<field name="model_id" |
|||
ref="detect_unauthorized_login.model_auto_capture"/> |
|||
<field name="email_from">{{user.company_id.email}}</field> |
|||
<field name="email_to">{{object.email}}</field> |
|||
<field name="subject">Password Incorrect</field> |
|||
<field name="body_html" type="html"> |
|||
<div style="margin: 0px; padding: 0px;"> |
|||
<p> |
|||
Dear<t t-out="ctx.get('user')"/>, |
|||
<br/> |
|||
<br/> |
|||
Suspicious sign in attempt to your odoo portal was |
|||
detected |
|||
. Unable to capture image as camera access was denied .. |
|||
<br/> |
|||
</p> |
|||
Regards, |
|||
<br/> |
|||
<t t-out="user.company_id.name"/> |
|||
</div> |
|||
</field> |
|||
</record> |
|||
</data> |
|||
</odoo> |
@ -0,0 +1,6 @@ |
|||
## Module <detect_unauthorized_login> |
|||
|
|||
#### 28.10.2024 |
|||
#### Version 18.0.1.0.0 |
|||
#### ADD |
|||
- Initial commit for Unauthorized Login Notification And Image Capture |
@ -0,0 +1,22 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
|||
# Author: Unnimaya CO (odoo@cybrosys.com) |
|||
# |
|||
# This program is free software: you can modify |
|||
# it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE (LGPL) as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU LESSER GENERAL PUBLIC LICENSE for more details. |
|||
# |
|||
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
|||
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
from . import auto_capture |
@ -0,0 +1,34 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
|||
# Author: Unnimaya CO (odoo@cybrosys.com) |
|||
# |
|||
# This program is free software: you can modify |
|||
# it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE (LGPL) as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU LESSER GENERAL PUBLIC LICENSE for more details. |
|||
# |
|||
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
|||
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
from odoo import fields, models |
|||
|
|||
|
|||
class AutoCapture(models.Model): |
|||
"""For storing the details of unauthorized access""" |
|||
_name = 'auto.capture' |
|||
_description = 'Auto Capture' |
|||
_rec_name = "date" |
|||
|
|||
email = fields.Char(string="Email", help="Mail ID of the user") |
|||
image = fields.Binary(string="Image", help="Image Of unauthorized user") |
|||
date = fields.Datetime(string="Date & Time", help="Date and Time of " |
|||
"unauthorized access") |
|
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 628 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 210 KiB |
After Width: | Height: | Size: 209 KiB |
After Width: | Height: | Size: 109 KiB |
After Width: | Height: | Size: 495 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 624 B |
After Width: | Height: | Size: 136 KiB |
After Width: | Height: | Size: 214 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 310 B |
After Width: | Height: | Size: 929 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 542 B |
After Width: | Height: | Size: 576 B |
After Width: | Height: | Size: 733 B |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 106 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 911 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 600 B |
After Width: | Height: | Size: 673 B |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 462 B |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 926 B |
After Width: | Height: | Size: 9.0 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 7.0 KiB |
After Width: | Height: | Size: 878 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 653 B |
After Width: | Height: | Size: 800 B |
After Width: | Height: | Size: 905 B |
After Width: | Height: | Size: 189 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 839 B |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 427 B |
After Width: | Height: | Size: 627 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 988 B |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 875 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 78 KiB |
After Width: | Height: | Size: 90 KiB |
After Width: | Height: | Size: 91 KiB |
After Width: | Height: | Size: 116 KiB |
After Width: | Height: | Size: 83 KiB |
After Width: | Height: | Size: 118 KiB |
After Width: | Height: | Size: 9.6 KiB |
After Width: | Height: | Size: 424 KiB |
After Width: | Height: | Size: 324 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 880 KiB |
After Width: | Height: | Size: 794 KiB |
After Width: | Height: | Size: 41 KiB |
@ -0,0 +1,50 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<odoo> |
|||
<!-- List view of auto capture model--> |
|||
<record id="auto_capture_view_list" model="ir.ui.view"> |
|||
<field name="name">auto.capture.view.list</field> |
|||
<field name="model">auto.capture</field> |
|||
<field name="arch" type="xml"> |
|||
<list> |
|||
<field name="email"/> |
|||
<field name="date"/> |
|||
</list> |
|||
</field> |
|||
</record> |
|||
<!-- Form view of auto capture model--> |
|||
<record id="auto_capture_view_form" model="ir.ui.view"> |
|||
<field name="name">auto.capture.view.form</field> |
|||
<field name="model">auto.capture</field> |
|||
<field name="arch" type="xml"> |
|||
<form> |
|||
<sheet> |
|||
<group> |
|||
<group> |
|||
<field name="email"/> |
|||
<field name="date"/> |
|||
<field name="image" widget="image"/> |
|||
</group> |
|||
</group> |
|||
</sheet> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
<!-- Action of menu wrong password--> |
|||
<record id="auto_capture_action" model="ir.actions.act_window"> |
|||
<field name="name">Wrong Password</field> |
|||
<field name="res_model">auto.capture</field> |
|||
<field name="view_mode">list,form</field> |
|||
</record> |
|||
<menuitem id="auto_capture_menu_root" |
|||
web_icon="detect_unauthorized_login,static/description/icon.png" |
|||
name="Detect Unauthorized Login" |
|||
action="auto_capture_action" |
|||
sequence="0" |
|||
/> |
|||
<menuitem id="auto_capture_menu" |
|||
name="Wrong Password" |
|||
action="auto_capture_action" |
|||
parent="auto_capture_menu_root" |
|||
sequence="2" |
|||
/> |
|||
</odoo> |