Сообщение #1
05 июня 2020, 13:37
|
Ограничение доступа по IP
Одно из решений ограничения доступа по IP к Оду
Пример базового кода
В контролере перехватываем http запросы до их обработки в Оду
Возможно внесение в белый и черный список, блокировка по частоте запросов и т.д.
Пример базового кода
from odoo import models,api
from odoo.http import Root
from odoo import registry as registry_get
from werkzeug.wrappers import BaseResponse as Response
class AccessIPs(models.Model):
_name = 'access_http.ip'
name = fields.Char(string='IP',index=True)
cnt = fields.Integer(string='Количество',default=1)
ban = fields.Boolean(string='Блокировка по IP', default=False)
access=fields.Boolean(string='Всегда доступен', default=False)
date=fields.Datetime(string="Время начала",default=datetime.utcnow())
group_ids=fields.Many2one('access_http.group',string="Группа доступа",default=1)
def get_access(self,ip):
res=self.sudo().search([('name','=',ip)],limit=1)
# здесь делаем нужную обработку по IP
if not res:
self.sudo().create(dict(name=ip))
return True
else:
if res.ban:
return False
if res.access:
return True
#try_count = 9 # Лимиты попыток
#try_time = 10 # Период лимита попыток в секундах за 10 секунд не более 9 соединений с одного ip
try_count=res.group_ids.try_count
dt = timedelta(days=0, hours=0, seconds=res.group_ids.try_time)
d1=datetime.strptime(res.date, '%Y-%m-%d %H:%M:%S')
if (datetime.utcnow()-dt-d1).total_seconds()<0: #промежуток попыток
if res.cnt > try_count: # Превышено количество запросов, повторите позже
return False
else:
res.sudo().write(dict(cnt=res.cnt+1)) # наращиваем счетчик запросов за заданный промежуток времени
return True
else: #Сбрасываем счетчик запросов по истечению времени лимита запросов
res.sudo().write(dict(cnt=1, date=datetime.utcnow()))
return True
В контролере перехватываем http запросы до их обработки в Оду
my_call=Root.__call__
def __call__(self,environ,start_response):
registry = registry_get(моя база)
with registry.cursor() as cr:
env = api.Environment(cr, api.SUPERUSER_ID, {})
cr.autocommit(True)
if not env['access_http.ip'].get_access(environ['REMOTE_ADDR'])
response = Response('Доступ заблокирован', status=403)
return response(environ, start_response)
return my_call(self, environ, start_response)
Root.__call__ = __call__
Возможно внесение в белый и черный список, блокировка по частоте запросов и т.д.
Последний раз редактировал пользователь
aladkoi
-
05 июня 2020, 13:51
0