2017-01-19 6 views
2

У меня есть приложение для бутылок на герою, и мне нужно отфильтровать входящие IP-адреса. Я не очень понимаю, как это сделать.IP-фильтрация в бутылке

This answer предлагает использовать обертку, но это для частных маршрутов - не для фильтрации входящих запросов. Обертка:

def private_only(route): 
    def wrapper(*args, **kwargs): 
     if IPy.IP(bottle.request.remote_addr).iptype() == 'PRIVATE': 
      return route(*args, **kwargs) 
     else: 
      return "Not allowed!" 
    return wrapper 

бы изменения обертке:

def private_only(route): 
    def wrapper(*args, **kwargs): 
     if IPy.IP(bottle.request.remote_addr).iptype() in ALLOWED_IPS: 
      return route(*args, **kwargs) 
     else: 
      return "Not allowed!" 
    return wrapper 

и декорирования маршрутов с:

@route('/my/internal/route') 
@private_only 
def my_view(): 
    return some_data() 

работы?

ответ

1

Если вы хотите включить фильтрацию для всего приложения для бутылок, я предлагаю вместо этого создать плагин. Приведенный ниже пример должен работать:

from bottle import request 
from bottle import HTTPError 
from bottle import app 

class IPFilteringPlugin(object): 
    name = 'ipfiltering' 
    api = 2 

    def __init__(self, allowed_ips=[]): 
     self.allowed_ips = allowed_ips 

    def apply(self, callback, route): 
     def wrapper(*a, **ka): 
      if request.remote_addr in self.allowed_ips: 
       return callback(*a, **ka) 
      raise HTTPError("Permission denied", status=403) 
     return wrapper 

app.install(IPFilteringPlugin(["127.0.0.1", "10.0.2.15"]) 

Следует также отметить, что вы можете использовать этот плагин только на маршрут, указав его в @route определения

filter_internal = IPFilteringPlugin(["127.0.0.1", "10.0.2.15"]) 
@route('/my/internal/route', apply=filter_internal) 
def internal_route(self): 
    pass 

# or directly route per route 
@route('/my/internal/route', apply=IPFilteringPlugin(["127.0.0.1", "10.0.2.15") 
def internal_route(self): 
    pass