]> git.ipfire.org Git - ipfire.org.git/blame - src/web/handlers_base.py
blog: Save timestamp when a feed has been updated last
[ipfire.org.git] / src / web / 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
a95c2f97 14from .. import util
60024cc8 15
940227cb 16class BaseHandler(tornado.web.RequestHandler):
4ca1a601
MT
17 @property
18 def hostname(self):
19 # Remove the development prefix
20 return self.request.host.replace(".dev.", ".")
21
bff08cb0
MT
22 def get_template_namespace(self):
23 ns = tornado.web.RequestHandler.get_template_namespace(self)
24
cc3b928d
MT
25 today = datetime.date.today()
26
bff08cb0 27 ns.update({
a95c2f97
MT
28 "format_size" : util.format_size,
29 "format_time" : util.format_time,
4ca1a601 30 "hostname" : self.hostname,
cc3b928d 31 "year" : today.year,
bff08cb0 32 })
940227cb 33
bff08cb0 34 return ns
940227cb 35
9068dba1
MT
36 def get_remote_ip(self):
37 # Fix for clients behind a proxy that sends "X-Forwarded-For".
66862195 38 remote_ips = self.request.remote_ip.split(", ")
494d80e6 39
66862195
MT
40 for remote_ip in remote_ips:
41 try:
42 addr = ipaddr.IPAddress(remote_ip)
43 except ValueError:
44 # Skip invalid IP addresses.
45 continue
9068dba1 46
66862195
MT
47 # Check if the given IP address is from a
48 # private network.
49 if addr.is_private:
50 continue
9068dba1 51
66862195 52 return remote_ip
9068dba1 53
494d80e6
MT
54 # Return the last IP if nothing else worked
55 return remote_ips.pop()
56
9068dba1
MT
57 def get_remote_location(self):
58 if not hasattr(self, "__remote_location"):
59 remote_ip = self.get_remote_ip()
60
61 self.__remote_location = self.geoip.get_location(remote_ip)
62
63 return self.__remote_location
64
bd2723d4
MT
65 def get_argument_int(self, *args, **kwargs):
66 arg = self.get_argument(*args, **kwargs)
67
68 if arg is None or arg == "":
69 return
70
71 try:
72 return int(arg)
73 except ValueError:
74 raise tornado.web.HTTPError(400)
75
66862195
MT
76 def get_argument_date(self, arg, *args, **kwargs):
77 value = self.get_argument(arg, *args, **kwargs)
78 if value is None:
79 return
80
81 try:
82 return dateutil.parser.parse(value)
83 except ValueError:
84 raise tornado.web.HTTPError(400)
85
86 # Login stuff
87
88 def get_current_user(self):
89 session_id = self.get_cookie("session_id")
90 if not session_id:
91 return
92
93 # Get account from the session object
94 account = self.backend.accounts.get_by_session(session_id, self.request.host)
95
96 # If the account was not found or the session was not valid
97 # any more, we will remove the cookie.
98 if not account:
99 self.clear_cookie("session_id")
100
101 return account
102
103 def login(self, username, password):
104 # Find account
105 account = self.backend.accounts.find_account(username)
106 if not account:
107 logging.warning(401, "unknown account: %s" % username)
108 return False
109
110 # Check credentials
111 if not account.check_password(password):
112 logging.warning("invalid password for %s" % account)
113 return False
114
115 # User has logged in, create a session
116 session_id, session_expires = self.backend.accounts.create_session(account,
117 self.request.host)
118
119 # Check if a new session was created
120 if not session_id:
121 logging.warning("Could not create session")
122 return False
123
124 # Send session cookie to the client
125 self.set_cookie("session_id", session_id,
126 domain=self.request.host, expires=session_expires)
127
128 return True
129
130 def logout(self):
131 session_id = self.get_cookie("session_id")
132
133 if not session_id:
134 return
135
136 success = self.backend.accounts.destroy_session(session_id, self.request.host)
137 if success:
138 self.clear_cookie("session_id")
139
a6dc0bad
MT
140 @property
141 def backend(self):
142 return self.application.backend
143
9068dba1
MT
144 @property
145 def db(self):
146 return self.backend.db
147
940227cb
MT
148 @property
149 def accounts(self):
a6dc0bad 150 return self.backend.accounts
940227cb
MT
151
152 @property
9068dba1
MT
153 def downloads(self):
154 return self.backend.downloads
155
66862195
MT
156 @property
157 def fireinfo(self):
158 return self.backend.fireinfo
159
9068dba1
MT
160 @property
161 def iuse(self):
162 return self.backend.iuse
940227cb 163
b3250465
MT
164 @property
165 def memcached(self):
9068dba1 166 return self.backend.memcache
b3250465 167
940227cb
MT
168 @property
169 def mirrors(self):
9068dba1
MT
170 return self.backend.mirrors
171
172 @property
173 def netboot(self):
174 return self.backend.netboot
940227cb 175
940227cb
MT
176 @property
177 def releases(self):
9068dba1 178 return self.backend.releases
940227cb
MT
179
180 @property
9068dba1
MT
181 def geoip(self):
182 return self.backend.geoip
940227cb
MT
183
184 @property
66862195
MT
185 def talk(self):
186 return self.backend.talk
940227cb 187
66862195
MT
188
189class LoginHandler(BaseHandler):
190 def get(self):
191 self.render("auth/login.html")
192
193 def post(self):
194 username = self.get_argument("username")
195 password = self.get_argument("password")
196
197 if not self.login(username, password):
198 raise tornado.web.HTTPError(401)
199
200 next = self.get_argument("next", "/")
201 return self.redirect(next)
202
203
204class LogoutHandler(BaseHandler):
205 def get(self):
206 self.logout()
207
208 # Get back to the start page
209 self.redirect("/")
3403dc5e
MT
210
211
212class NotFoundHandler(BaseHandler):
213 def prepare(self):
214 # Raises 404 as soon as it is called
215 raise tornado.web.HTTPError(404)
216
217 def write_error(self, status_code, **kwargs):
218 assert status_code == 404
219
220 self.render("error-404.html")