]> git.ipfire.org Git - people/shoehn/ipfire.org.git/blob - webapp/handlers_base.py
mirrors: Sort by distance (ascending)
[people/shoehn/ipfire.org.git] / webapp / handlers_base.py
1 #!/usr/bin/python
2
3 from __future__ import division
4
5 import datetime
6 import dateutil.parser
7 import httplib
8 import ipaddr
9 import logging
10 import time
11 import tornado.locale
12 import tornado.web
13
14 import backend.util
15
16 class BaseHandler(tornado.web.RequestHandler):
17 rss_url = None
18
19 def get_account(self, uid):
20 # Find the name of the author
21 return self.accounts.find(uid)
22
23 def get_user_locale(self):
24 # The planet is always in english.
25 if self.hostname == "planet.ipfire.org":
26 return tornado.locale.get("en_US")
27
28 # Otherwise take the browser locale.
29 return self.get_browser_locale()
30
31 @property
32 def hostname(self):
33 # Remove the development prefix
34 return self.request.host.replace(".dev.", ".")
35
36 @property
37 def ssl_params(self):
38 return {
39 "ssl_cipher" : self.request.headers.get("X-Https-Cipher", None),
40 "ssl_protocol" : self.request.headers.get("X-Https-Protocol", None),
41 }
42
43 @property
44 def render_args(self):
45 today = datetime.date.today()
46
47 ret = {
48 "format_size" : backend.util.format_size,
49 "format_time" : backend.util.format_time,
50 "hostname" : self.hostname,
51 "lang" : self.locale.code[:2],
52 "rss_url" : self.rss_url,
53 "year" : today.year,
54 }
55 ret.update(self.ssl_params)
56
57 return ret
58
59 def render(self, *args, **_kwargs):
60 kwargs = self.render_args
61 kwargs.update(_kwargs)
62 tornado.web.RequestHandler.render(self, *args, **kwargs)
63
64 def render_string(self, *args, **_kwargs):
65 kwargs = self.render_args
66 kwargs.update(_kwargs)
67 return tornado.web.RequestHandler.render_string(self, *args, **kwargs)
68
69 def write_error(self, status_code, **kwargs):
70 if status_code in (404, 500):
71 render_args = ({
72 "code" : status_code,
73 "exception" : kwargs.get("exception", None),
74 "message" : httplib.responses[status_code],
75 })
76 self.render("error-%s.html" % status_code, **render_args)
77 else:
78 return tornado.web.RequestHandler.write_error(self, status_code, **kwargs)
79
80 def static_url(self, path, static=True):
81 ret = tornado.web.RequestHandler.static_url(self, path)
82
83 if self.settings.get("debug", False):
84 return ret
85
86 if static:
87 return "//static.ipfire.org%s" % ret
88
89 return ret
90
91 def get_remote_ip(self):
92 # Fix for clients behind a proxy that sends "X-Forwarded-For".
93 remote_ips = self.request.remote_ip.split(", ")
94
95 for remote_ip in remote_ips:
96 try:
97 addr = ipaddr.IPAddress(remote_ip)
98 except ValueError:
99 # Skip invalid IP addresses.
100 continue
101
102 # Check if the given IP address is from a
103 # private network.
104 if addr.is_private:
105 continue
106
107 return remote_ip
108
109 # Return the last IP if nothing else worked
110 return remote_ips.pop()
111
112 def get_remote_location(self):
113 if not hasattr(self, "__remote_location"):
114 remote_ip = self.get_remote_ip()
115
116 self.__remote_location = self.geoip.get_location(remote_ip)
117
118 return self.__remote_location
119
120 def get_argument_date(self, arg, *args, **kwargs):
121 value = self.get_argument(arg, *args, **kwargs)
122 if value is None:
123 return
124
125 try:
126 return dateutil.parser.parse(value)
127 except ValueError:
128 raise tornado.web.HTTPError(400)
129
130 # Login stuff
131
132 def get_current_user(self):
133 session_id = self.get_cookie("session_id")
134 if not session_id:
135 return
136
137 # Get account from the session object
138 account = self.backend.accounts.get_by_session(session_id, self.request.host)
139
140 # If the account was not found or the session was not valid
141 # any more, we will remove the cookie.
142 if not account:
143 self.clear_cookie("session_id")
144
145 return account
146
147 def login(self, username, password):
148 # Find account
149 account = self.backend.accounts.find_account(username)
150 if not account:
151 logging.warning(401, "unknown account: %s" % username)
152 return False
153
154 # Check credentials
155 if not account.check_password(password):
156 logging.warning("invalid password for %s" % account)
157 return False
158
159 # User has logged in, create a session
160 session_id, session_expires = self.backend.accounts.create_session(account,
161 self.request.host)
162
163 # Check if a new session was created
164 if not session_id:
165 logging.warning("Could not create session")
166 return False
167
168 # Send session cookie to the client
169 self.set_cookie("session_id", session_id,
170 domain=self.request.host, expires=session_expires)
171
172 return True
173
174 def logout(self):
175 session_id = self.get_cookie("session_id")
176
177 if not session_id:
178 return
179
180 success = self.backend.accounts.destroy_session(session_id, self.request.host)
181 if success:
182 self.clear_cookie("session_id")
183
184 @property
185 def backend(self):
186 return self.application.backend
187
188 @property
189 def db(self):
190 return self.backend.db
191
192 @property
193 def advertisements(self):
194 return self.backend.advertisements
195
196 @property
197 def accounts(self):
198 return self.backend.accounts
199
200 @property
201 def downloads(self):
202 return self.backend.downloads
203
204 @property
205 def fireinfo(self):
206 return self.backend.fireinfo
207
208 @property
209 def iuse(self):
210 return self.backend.iuse
211
212 @property
213 def memcached(self):
214 return self.backend.memcache
215
216 @property
217 def mirrors(self):
218 return self.backend.mirrors
219
220 @property
221 def netboot(self):
222 return self.backend.netboot
223
224 @property
225 def news(self):
226 return self.backend.news
227
228 @property
229 def config(self):
230 return self.backend.settings
231
232 @property
233 def releases(self):
234 return self.backend.releases
235
236 @property
237 def geoip(self):
238 return self.backend.geoip
239
240 @property
241 def talk(self):
242 return self.backend.talk
243
244 @property
245 def tracker(self):
246 return self.backend.tracker
247
248 @property
249 def planet(self):
250 return self.backend.planet
251
252 @property
253 def wishlist(self):
254 return self.backend.wishlist
255
256
257 class LoginHandler(BaseHandler):
258 def get(self):
259 self.render("auth/login.html")
260
261 def post(self):
262 username = self.get_argument("username")
263 password = self.get_argument("password")
264
265 if not self.login(username, password):
266 raise tornado.web.HTTPError(401)
267
268 next = self.get_argument("next", "/")
269 return self.redirect(next)
270
271
272 class LogoutHandler(BaseHandler):
273 def get(self):
274 self.logout()
275
276 # Get back to the start page
277 self.redirect("/")