]>
Commit | Line | Data |
---|---|---|
940227cb MT |
1 | #!/usr/bin/python |
2 | ||
60024cc8 MT |
3 | from __future__ import division |
4 | ||
cc3b928d | 5 | import datetime |
66862195 MT |
6 | import dateutil.parser |
7 | import httplib | |
8 | import ipaddr | |
47ed77ed | 9 | import logging |
940227cb MT |
10 | import time |
11 | import tornado.locale | |
12 | import tornado.web | |
13 | ||
a95c2f97 | 14 | from .. import util |
60024cc8 | 15 | |
940227cb | 16 | class 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 | |
189 | class 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 | ||
204 | class LogoutHandler(BaseHandler): | |
205 | def get(self): | |
206 | self.logout() | |
207 | ||
208 | # Get back to the start page | |
209 | self.redirect("/") | |
3403dc5e MT |
210 | |
211 | ||
212 | class 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") |