]>
git.ipfire.org Git - ipfire.org.git/blob - src/web/base.py
13 from ..decorators
import *
16 class ratelimit(object):
17 def __init__(self
, minutes
=15, requests
=180):
18 self
.minutes
= minutes
19 self
.requests
= requests
21 def __call__(self
, method
):
22 @functools.wraps(method
)
23 def wrapper(handler
, *args
, **kwargs
):
24 # Pass the request to the rate limiter and get a request object
25 req
= handler
.backend
.ratelimiter
.handle_request(handler
.request
,
26 handler
, minutes
=self
.minutes
, limit
=self
.requests
)
28 # If the rate limit has been reached, we won't allow
29 # processing the request and therefore send HTTP error code 429.
30 if req
.is_ratelimited():
31 raise tornado
.web
.HTTPError(429, "Rate limit exceeded")
33 return method(handler
, *args
, **kwargs
)
38 class BaseHandler(tornado
.web
.RequestHandler
):
39 def set_expires(self
, seconds
):
41 self
.add_header("Cache-Control", "max-age=%s, must-revalidate" % seconds
)
44 expires
= datetime
.datetime
.utcnow() + datetime
.timedelta(seconds
=seconds
)
45 self
.add_header("Expires", expires
)
47 def write_error(self
, status_code
, **kwargs
):
48 # Translate code into message
50 message
= http
.client
.responses
[status_code
]
54 self
.render("error.html", status_code
=status_code
, message
=message
, **kwargs
)
56 def xsrf_form_html(self
, *args
, **kwargs
):
57 # Set Vary: Cookie header
58 self
.add_header("Vary", "Cookie")
60 return super().xsrf_form_html(*args
, **kwargs
)
64 # Remove the development prefix
65 return self
.request
.host
.replace(".dev.", ".")
67 def get_template_namespace(self
):
68 ns
= tornado
.web
.RequestHandler
.get_template_namespace(self
)
70 now
= datetime
.date
.today()
73 "backend" : self
.backend
,
74 "debug" : self
.application
.settings
.get("debug", False),
75 "format_size" : util
.format_size
,
76 "format_time" : util
.format_time
,
77 "hostname" : self
.hostname
,
84 def get_remote_ip(self
):
85 # Fix for clients behind a proxy that sends "X-Forwarded-For".
86 remote_ips
= self
.request
.remote_ip
.split(", ")
88 for remote_ip
in remote_ips
:
90 addr
= ipaddress
.ip_address(remote_ip
)
92 # Skip invalid IP addresses.
95 # Check if the given IP address is from a
102 # Return the last IP if nothing else worked
103 return remote_ips
.pop()
106 def current_address(self
):
107 address
= self
.get_remote_ip()
110 return util
.Address(self
.backend
, address
)
113 def current_country_code(self
):
114 if self
.current_address
:
115 return self
.current_address
.country_code
117 def get_argument_int(self
, *args
, **kwargs
):
118 arg
= self
.get_argument(*args
, **kwargs
)
120 if arg
is None or arg
== "":
126 raise tornado
.web
.HTTPError(400, "Could not convert integer: %s" % arg
)
128 def get_argument_float(self
, *args
, **kwargs
):
129 arg
= self
.get_argument(*args
, **kwargs
)
131 if arg
is None or arg
== "":
137 raise tornado
.web
.HTTPError(400, "Could not convert float: %s" % arg
)
139 def get_argument_date(self
, arg
, *args
, **kwargs
):
140 value
= self
.get_argument(arg
, *args
, **kwargs
)
145 return dateutil
.parser
.parse(value
)
147 raise tornado
.web
.HTTPError(400)
149 def get_file(self
, name
):
151 file = self
.request
.files
[name
][0]
153 return file["filename"], file["body"], file["content_type"]
159 def get_current_user(self
):
160 session_id
= self
.get_cookie("session_id")
164 # Get account from the session object
165 account
= self
.backend
.accounts
.get_by_session(session_id
, self
.request
.host
)
167 # If the account was not found or the session was not valid
168 # any more, we will remove the cookie.
170 self
.clear_cookie("session_id")
176 return self
.application
.backend
180 return self
.backend
.db
184 return self
.backend
.accounts
188 return self
.backend
.downloads
192 return self
.backend
.fireinfo
196 return self
.backend
.iuse
200 return self
.backend
.memcache
204 return self
.backend
.mirrors
208 return self
.backend
.netboot
212 return self
.backend
.releases
216 return self
.backend
.talk
219 class APIHandler(BaseHandler
):
220 def check_xsrf_cookie(self
):
222 Do nothing here, because we cannot verify the XSRF token
227 class NotFoundHandler(BaseHandler
):
229 # Raises 404 as soon as it is called
230 raise tornado
.web
.HTTPError(404)
233 class ErrorHandler(BaseHandler
):
235 Raises any error we want
241 raise tornado
.web
.HTTPError(400)
243 raise tornado
.web
.HTTPError(code
)