]> git.ipfire.org Git - people/shoehn/ipfire.org.git/blame - webapp/handlers_base.py
adjust touch target on mobile Feature page
[people/shoehn/ipfire.org.git] / webapp / handlers_base.py
CommitLineData
940227cb
MT
1#!/usr/bin/python
2
60024cc8
MT
3from __future__ import division
4
cc3b928d 5import datetime
66862195
MT
6import dateutil.parser
7import httplib
8import ipaddr
47ed77ed 9import logging
940227cb
MT
10import time
11import tornado.locale
12import tornado.web
13
66862195 14import backend.util
60024cc8 15
940227cb 16class BaseHandler(tornado.web.RequestHandler):
de683d7c
MT
17 rss_url = None
18
940227cb
MT
19 def get_account(self, uid):
20 # Find the name of the author
21 return self.accounts.find(uid)
22
60024cc8 23 def get_user_locale(self):
45c763aa 24 # The planet is always in english.
4ca1a601 25 if self.hostname == "planet.ipfire.org":
dbf95cf2 26 return tornado.locale.get("en_US")
45c763aa 27
dbf95cf2
MT
28 # Otherwise take the browser locale.
29 return self.get_browser_locale()
940227cb 30
4ca1a601
MT
31 @property
32 def hostname(self):
33 # Remove the development prefix
34 return self.request.host.replace(".dev.", ".")
35
47d47c2e
MT
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
940227cb
MT
43 @property
44 def render_args(self):
cc3b928d
MT
45 today = datetime.date.today()
46
47d47c2e 47 ret = {
66862195
MT
48 "format_size" : backend.util.format_size,
49 "format_time" : backend.util.format_time,
4ca1a601 50 "hostname" : self.hostname,
940227cb 51 "lang" : self.locale.code[:2],
de683d7c 52 "rss_url" : self.rss_url,
cc3b928d 53 "year" : today.year,
940227cb 54 }
47d47c2e
MT
55 ret.update(self.ssl_params)
56
57 return ret
940227cb 58
bcc3ed4d
MT
59 def render(self, *args, **_kwargs):
60 kwargs = self.render_args
61 kwargs.update(_kwargs)
940227cb
MT
62 tornado.web.RequestHandler.render(self, *args, **kwargs)
63
bcc3ed4d
MT
64 def render_string(self, *args, **_kwargs):
65 kwargs = self.render_args
66 kwargs.update(_kwargs)
940227cb
MT
67 return tornado.web.RequestHandler.render_string(self, *args, **kwargs)
68
02f2d7fe 69 def write_error(self, status_code, **kwargs):
940227cb
MT
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 })
02f2d7fe 76 self.render("error-%s.html" % status_code, **render_args)
940227cb 77 else:
02f2d7fe 78 return tornado.web.RequestHandler.write_error(self, status_code, **kwargs)
940227cb 79
3d540c40
MT
80 def static_url(self, path, static=True):
81 ret = tornado.web.RequestHandler.static_url(self, path)
82
1de8dd23
MT
83 if self.settings.get("debug", False):
84 return ret
85
4fc4823e
MT
86 if static:
87 return "//static.ipfire.org%s" % ret
3d540c40
MT
88
89 return ret
90
9068dba1
MT
91 def get_remote_ip(self):
92 # Fix for clients behind a proxy that sends "X-Forwarded-For".
66862195 93 remote_ips = self.request.remote_ip.split(", ")
494d80e6 94
66862195
MT
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
9068dba1 101
66862195
MT
102 # Check if the given IP address is from a
103 # private network.
104 if addr.is_private:
105 continue
9068dba1 106
66862195 107 return remote_ip
9068dba1 108
494d80e6
MT
109 # Return the last IP if nothing else worked
110 return remote_ips.pop()
111
9068dba1
MT
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
66862195
MT
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
a6dc0bad
MT
184 @property
185 def backend(self):
186 return self.application.backend
187
9068dba1
MT
188 @property
189 def db(self):
190 return self.backend.db
191
a0048e66
MT
192 @property
193 def advertisements(self):
9068dba1 194 return self.backend.advertisements
a0048e66 195
940227cb
MT
196 @property
197 def accounts(self):
a6dc0bad 198 return self.backend.accounts
940227cb
MT
199
200 @property
9068dba1
MT
201 def downloads(self):
202 return self.backend.downloads
203
66862195
MT
204 @property
205 def fireinfo(self):
206 return self.backend.fireinfo
207
9068dba1
MT
208 @property
209 def iuse(self):
210 return self.backend.iuse
940227cb 211
b3250465
MT
212 @property
213 def memcached(self):
9068dba1 214 return self.backend.memcache
b3250465 215
940227cb
MT
216 @property
217 def mirrors(self):
9068dba1
MT
218 return self.backend.mirrors
219
220 @property
221 def netboot(self):
222 return self.backend.netboot
940227cb
MT
223
224 @property
225 def news(self):
9068dba1 226 return self.backend.news
940227cb
MT
227
228 @property
229 def config(self):
9068dba1 230 return self.backend.settings
940227cb
MT
231
232 @property
233 def releases(self):
9068dba1 234 return self.backend.releases
940227cb
MT
235
236 @property
9068dba1
MT
237 def geoip(self):
238 return self.backend.geoip
940227cb
MT
239
240 @property
66862195
MT
241 def talk(self):
242 return self.backend.talk
940227cb
MT
243
244 @property
245 def tracker(self):
9068dba1 246 return self.backend.tracker
bcc3ed4d
MT
247
248 @property
249 def planet(self):
a6dc0bad 250 return self.backend.planet
7771acea
MT
251
252 @property
253 def wishlist(self):
9068dba1 254 return self.backend.wishlist
66862195
MT
255
256
257class 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
272class LogoutHandler(BaseHandler):
273 def get(self):
274 self.logout()
275
276 # Get back to the start page
277 self.redirect("/")