Reputation: 2669
I have a Bottle app on heroku, and I need to filter inbound IP addresses. I don't have much idea how to do this.
This answer suggests using a wrapper, but this is for private routes - not filtering inbound requests. The wrapper is:
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
Would changing the wrapper to:
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
and decorating routes with:
@route('/my/internal/route')
@private_only
def my_view():
return some_data()
work?
Upvotes: 2
Views: 501
Reputation: 2668
If you want to enable filtering for the entire bottle application, I suggest to create a plugin instead. The example below should work:
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"])
Note as well that you can use this plugin only per route, by specifying it in the @route
definition
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
Upvotes: 2