]>
git.ipfire.org Git - ipfire.org.git/blob - src/web/base.py
b92ad74fa109e8375c6efb396962c3f59116dfe3
13 from ..decorators
import *
16 def blacklisted(method
):
17 @tornado.gen
.coroutine
18 @functools.wraps(method
)
19 def wrapper(self
, *args
, **kwargs
):
20 # Check if remote is blacklisted
21 is_blacklisted
= yield self
.remote
.is_blacklisted()
23 # If so, redirect to the blocked page
25 logging
.warning("%s is blacklisted" % self
.remote
)
27 return self
.redirect("https://www.ipfire.org/blocked")
29 return method(self
, *args
, **kwargs
)
33 class ratelimit(object):
34 def __init__(self
, minutes
=15, requests
=180):
35 self
.minutes
= minutes
36 self
.requests
= requests
38 def __call__(self
, method
):
39 @functools.wraps(method
)
40 def wrapper(handler
, *args
, **kwargs
):
41 # Pass the request to the rate limiter and get a request object
42 req
= handler
.backend
.ratelimiter
.handle_request(handler
.request
,
43 handler
, minutes
=self
.minutes
, limit
=self
.requests
)
45 # If the rate limit has been reached, we won't allow
46 # processing the request and therefore send HTTP error code 429.
47 if req
.is_ratelimited():
48 raise tornado
.web
.HTTPError(429, "Rate limit exceeded")
50 return method(handler
, *args
, **kwargs
)
55 class BaseHandler(tornado
.web
.RequestHandler
):
56 def set_expires(self
, seconds
):
58 self
.add_header("Cache-Control", "max-age=%s, must-revalidate" % seconds
)
61 expires
= datetime
.datetime
.utcnow() + datetime
.timedelta(seconds
=seconds
)
62 self
.add_header("Expires", expires
)
64 def write_error(self
, status_code
, **kwargs
):
65 # Translate code into message
67 message
= http
.client
.responses
[status_code
]
71 self
.render("error.html", status_code
=status_code
, message
=message
, **kwargs
)
73 def xsrf_form_html(self
, *args
, **kwargs
):
74 # Set Vary: Cookie header
75 self
.add_header("Vary", "Cookie")
77 return super().xsrf_form_html(*args
, **kwargs
)
81 # Remove the development prefix
82 return self
.request
.host
.replace(".dev.", ".")
84 def get_template_namespace(self
):
85 ns
= tornado
.web
.RequestHandler
.get_template_namespace(self
)
87 now
= datetime
.date
.today()
90 "backend" : self
.backend
,
91 "debug" : self
.application
.settings
.get("debug", False),
92 "format_size" : util
.format_size
,
93 "format_time" : util
.format_time
,
94 "hostname" : self
.hostname
,
101 def get_remote_ip(self
):
102 # Fix for clients behind a proxy that sends "X-Forwarded-For".
103 remote_ips
= self
.request
.remote_ip
.split(", ")
105 for remote_ip
in remote_ips
:
107 addr
= ipaddress
.ip_address(remote_ip
)
109 # Skip invalid IP addresses.
112 # Check if the given IP address is from a
119 # Return the last IP if nothing else worked
120 return remote_ips
.pop()
124 address
= self
.get_remote_ip()
127 return self
.backend
.geoip
.lookup(address
)
130 def current_country_code(self
):
131 remote_ip
= self
.get_remote_ip()
134 return self
.backend
.geoip
.get_country(remote_ip
)
136 def get_remote_location(self
):
137 if not hasattr(self
, "__remote_location"):
138 remote_ip
= self
.get_remote_ip()
140 self
.__remote
_location
= self
.geoip
.get_location(remote_ip
)
142 return self
.__remote
_location
144 def get_argument_int(self
, *args
, **kwargs
):
145 arg
= self
.get_argument(*args
, **kwargs
)
147 if arg
is None or arg
== "":
153 raise tornado
.web
.HTTPError(400)
155 def get_argument_date(self
, arg
, *args
, **kwargs
):
156 value
= self
.get_argument(arg
, *args
, **kwargs
)
161 return dateutil
.parser
.parse(value
)
163 raise tornado
.web
.HTTPError(400)
165 def get_file(self
, name
):
167 file = self
.request
.files
[name
][0]
169 return file["filename"], file["body"], file["content_type"]
175 def get_current_user(self
):
176 session_id
= self
.get_cookie("session_id")
180 # Get account from the session object
181 account
= self
.backend
.accounts
.get_by_session(session_id
, self
.request
.host
)
183 # If the account was not found or the session was not valid
184 # any more, we will remove the cookie.
186 self
.clear_cookie("session_id")
192 return self
.application
.backend
196 return self
.backend
.db
200 return self
.backend
.accounts
204 return self
.backend
.downloads
208 return self
.backend
.fireinfo
212 return self
.backend
.iuse
216 return self
.backend
.memcache
220 return self
.backend
.mirrors
224 return self
.backend
.netboot
228 return self
.backend
.releases
232 return self
.backend
.geoip
236 return self
.backend
.talk
239 class NotFoundHandler(BaseHandler
):
241 # Raises 404 as soon as it is called
242 raise tornado
.web
.HTTPError(404)
245 class ErrorHandler(BaseHandler
):
247 Raises any error we want
253 raise tornado
.web
.HTTPError(400)
255 raise tornado
.web
.HTTPError(code
)
258 class BlockedHandler(BaseHandler
):
263 self
.render("static/blocked.html", address
=self
.get_remote_ip())