]> git.ipfire.org Git - ipfire.org.git/blame - src/web/base.py
Merge remote-tracking branch 'origin/master'
[ipfire.org.git] / src / web / base.py
CommitLineData
940227cb
MT
1#!/usr/bin/python
2
cc3b928d 3import datetime
66862195 4import dateutil.parser
11347e46 5import http.client
a69e87a1 6import ipaddress
47ed77ed 7import logging
940227cb
MT
8import time
9import tornado.locale
10import tornado.web
11
f110a9ff 12from ..decorators import *
a95c2f97 13from .. import util
60024cc8 14
940227cb 15class BaseHandler(tornado.web.RequestHandler):
f6ed3d4d
MT
16 def set_expires(self, seconds):
17 # For HTTP/1.1
b592d7c8 18 self.add_header("Cache-Control", "max-age=%s, must-revalidate" % seconds)
f6ed3d4d
MT
19
20 # For HTTP/1.0
21 expires = datetime.datetime.utcnow() + datetime.timedelta(seconds=seconds)
b592d7c8 22 self.add_header("Expires", expires)
f6ed3d4d 23
37ed7c3c
MT
24 def write_error(self, status_code, **kwargs):
25 # Translate code into message
26 try:
11347e46 27 message = http.client.responses[status_code]
37ed7c3c
MT
28 except KeyError:
29 message = None
30
31 self.render("error.html", status_code=status_code, message=message, **kwargs)
32
4ca1a601
MT
33 @property
34 def hostname(self):
35 # Remove the development prefix
36 return self.request.host.replace(".dev.", ".")
37
bff08cb0
MT
38 def get_template_namespace(self):
39 ns = tornado.web.RequestHandler.get_template_namespace(self)
40
911064cf 41 now = datetime.date.today()
cc3b928d 42
bff08cb0 43 ns.update({
5613b94b 44 "debug" : self.application.settings.get("debug", False),
a95c2f97
MT
45 "format_size" : util.format_size,
46 "format_time" : util.format_time,
4ca1a601 47 "hostname" : self.hostname,
911064cf
MT
48 "now" : now,
49 "year" : now.year,
bff08cb0 50 })
940227cb 51
bff08cb0 52 return ns
940227cb 53
9068dba1
MT
54 def get_remote_ip(self):
55 # Fix for clients behind a proxy that sends "X-Forwarded-For".
66862195 56 remote_ips = self.request.remote_ip.split(", ")
494d80e6 57
66862195
MT
58 for remote_ip in remote_ips:
59 try:
a69e87a1 60 addr = ipaddress.ip_address(remote_ip)
66862195
MT
61 except ValueError:
62 # Skip invalid IP addresses.
63 continue
9068dba1 64
66862195
MT
65 # Check if the given IP address is from a
66 # private network.
67 if addr.is_private:
68 continue
9068dba1 69
66862195 70 return remote_ip
9068dba1 71
494d80e6
MT
72 # Return the last IP if nothing else worked
73 return remote_ips.pop()
74
f110a9ff
MT
75 @lazy_property
76 def current_country_code(self):
77 remote_ip = self.get_remote_ip()
78
79 if remote_ip:
80 return self.backend.geoip.get_country(remote_ip)
81
9068dba1
MT
82 def get_remote_location(self):
83 if not hasattr(self, "__remote_location"):
84 remote_ip = self.get_remote_ip()
85
86 self.__remote_location = self.geoip.get_location(remote_ip)
87
88 return self.__remote_location
89
bd2723d4
MT
90 def get_argument_int(self, *args, **kwargs):
91 arg = self.get_argument(*args, **kwargs)
92
93 if arg is None or arg == "":
94 return
95
96 try:
97 return int(arg)
98 except ValueError:
99 raise tornado.web.HTTPError(400)
100
66862195
MT
101 def get_argument_date(self, arg, *args, **kwargs):
102 value = self.get_argument(arg, *args, **kwargs)
103 if value is None:
104 return
105
106 try:
107 return dateutil.parser.parse(value)
108 except ValueError:
109 raise tornado.web.HTTPError(400)
110
5cc10421
MT
111 def get_file(self, name):
112 try:
113 file = self.request.files[name][0]
114
115 return file["filename"], file["body"], file["content_type"]
116 except KeyError:
117 return None
118
66862195
MT
119 # Login stuff
120
121 def get_current_user(self):
122 session_id = self.get_cookie("session_id")
123 if not session_id:
124 return
125
126 # Get account from the session object
127 account = self.backend.accounts.get_by_session(session_id, self.request.host)
128
129 # If the account was not found or the session was not valid
130 # any more, we will remove the cookie.
131 if not account:
132 self.clear_cookie("session_id")
133
134 return account
135
a6dc0bad
MT
136 @property
137 def backend(self):
138 return self.application.backend
139
9068dba1
MT
140 @property
141 def db(self):
142 return self.backend.db
143
940227cb
MT
144 @property
145 def accounts(self):
a6dc0bad 146 return self.backend.accounts
940227cb
MT
147
148 @property
9068dba1
MT
149 def downloads(self):
150 return self.backend.downloads
151
66862195
MT
152 @property
153 def fireinfo(self):
154 return self.backend.fireinfo
155
9068dba1
MT
156 @property
157 def iuse(self):
158 return self.backend.iuse
940227cb
MT
159
160 @property
161 def mirrors(self):
9068dba1
MT
162 return self.backend.mirrors
163
164 @property
165 def netboot(self):
166 return self.backend.netboot
940227cb 167
940227cb
MT
168 @property
169 def releases(self):
9068dba1 170 return self.backend.releases
940227cb
MT
171
172 @property
9068dba1
MT
173 def geoip(self):
174 return self.backend.geoip
940227cb
MT
175
176 @property
66862195
MT
177 def talk(self):
178 return self.backend.talk
940227cb 179
66862195 180
3403dc5e
MT
181class NotFoundHandler(BaseHandler):
182 def prepare(self):
183 # Raises 404 as soon as it is called
184 raise tornado.web.HTTPError(404)
185
3403dc5e 186
37ed7c3c
MT
187class ErrorHandler(BaseHandler):
188 """
189 Raises any error we want
190 """
191 def get(self, code):
192 try:
193 code = int(code)
194 except:
195 raise tornado.web.HTTPError(400)
196
197 raise tornado.web.HTTPError(code)
baa693a3
MT
198
199
200class BlockedHandler(BaseHandler):
201 def get(self):
202 # 403 - Forbidden
203 self.set_status(403)
204
205 self.render("static/blocked.html", address=self.get_remote_ip())