from __future__ import division
-import httplib
import datetime
+import dateutil.parser
+import httplib
+import ipaddr
+import logging
import time
import tornado.locale
import tornado.web
-def format_size(b):
- units = ["B", "k", "M", "G"]
- unit_pointer = 0
-
- while b >= 1024 and unit_pointer < len(units):
- b /= 1024
- unit_pointer += 1
-
- return "%.1f%s" % (b, units[unit_pointer])
-
+import backend.util
class BaseHandler(tornado.web.RequestHandler):
rss_url = None
# Find the name of the author
return self.accounts.find(uid)
- def get_query_locale(self):
- locale = self.get_argument("locale", None)
-
- if locale is None:
- return
-
- return tornado.locale.get(locale)
-
- def prepare(self):
- locale = self.get_query_locale()
- if locale:
- self.set_cookie("locale", locale.code)
-
def get_user_locale(self):
# The planet is always in english.
- if self.request.host == "planet.ipfire.org":
+ if self.hostname == "planet.ipfire.org":
return tornado.locale.get("en_US")
- # Get the locale from the query.
- locale = self.get_query_locale()
- if locale:
- return locale
-
- # Read the locale from the cookies.
- locale = self.get_cookie("locale", None)
- if locale:
- return tornado.locale.get(locale)
-
# Otherwise take the browser locale.
return self.get_browser_locale()
+ @property
+ def hostname(self):
+ # Remove the development prefix
+ return self.request.host.replace(".dev.", ".")
+
+ @property
+ def ssl_params(self):
+ return {
+ "ssl_cipher" : self.request.headers.get("X-Https-Cipher", None),
+ "ssl_protocol" : self.request.headers.get("X-Https-Protocol", None),
+ }
+
@property
def render_args(self):
today = datetime.date.today()
- return {
- "format_size" : format_size,
- "hostname" : self.request.host,
+ ret = {
+ "format_size" : backend.util.format_size,
+ "format_time" : backend.util.format_time,
+ "hostname" : self.hostname,
"lang" : self.locale.code[:2],
"rss_url" : self.rss_url,
"year" : today.year,
}
+ ret.update(self.ssl_params)
+
+ return ret
def render(self, *args, **_kwargs):
kwargs = self.render_args
def static_url(self, path, static=True):
ret = tornado.web.RequestHandler.static_url(self, path)
-
+ if self.settings.get("debug", False):
+ return ret
+
+ if static:
+ return "//static.ipfire.org%s" % ret
return ret
def get_remote_ip(self):
# Fix for clients behind a proxy that sends "X-Forwarded-For".
- ip_addr = self.request.remote_ip.split(", ")
+ remote_ips = self.request.remote_ip.split(", ")
+
+ for remote_ip in remote_ips:
+ try:
+ addr = ipaddr.IPAddress(remote_ip)
+ except ValueError:
+ # Skip invalid IP addresses.
+ continue
+
+ # Check if the given IP address is from a
+ # private network.
+ if addr.is_private:
+ continue
- if ip_addr:
- ip_addr = ip_addr[-1]
+ return remote_ip
- return ip_addr
+ # Return the last IP if nothing else worked
+ return remote_ips.pop()
def get_remote_location(self):
if not hasattr(self, "__remote_location"):
return self.__remote_location
+ def get_argument_date(self, arg, *args, **kwargs):
+ value = self.get_argument(arg, *args, **kwargs)
+ if value is None:
+ return
+
+ try:
+ return dateutil.parser.parse(value)
+ except ValueError:
+ raise tornado.web.HTTPError(400)
+
+ # Login stuff
+
+ def get_current_user(self):
+ session_id = self.get_cookie("session_id")
+ if not session_id:
+ return
+
+ # Get account from the session object
+ account = self.backend.accounts.get_by_session(session_id, self.request.host)
+
+ # If the account was not found or the session was not valid
+ # any more, we will remove the cookie.
+ if not account:
+ self.clear_cookie("session_id")
+
+ return account
+
+ def login(self, username, password):
+ # Find account
+ account = self.backend.accounts.find_account(username)
+ if not account:
+ logging.warning(401, "unknown account: %s" % username)
+ return False
+
+ # Check credentials
+ if not account.check_password(password):
+ logging.warning("invalid password for %s" % account)
+ return False
+
+ # User has logged in, create a session
+ session_id, session_expires = self.backend.accounts.create_session(account,
+ self.request.host)
+
+ # Check if a new session was created
+ if not session_id:
+ logging.warning("Could not create session")
+ return False
+
+ # Send session cookie to the client
+ self.set_cookie("session_id", session_id,
+ domain=self.request.host, expires=session_expires)
+
+ return True
+
+ def logout(self):
+ session_id = self.get_cookie("session_id")
+
+ if not session_id:
+ return
+
+ success = self.backend.accounts.destroy_session(session_id, self.request.host)
+ if success:
+ self.clear_cookie("session_id")
+
@property
def backend(self):
return self.application.backend
def downloads(self):
return self.backend.downloads
+ @property
+ def fireinfo(self):
+ return self.backend.fireinfo
+
@property
def iuse(self):
return self.backend.iuse
return self.backend.geoip
@property
- def stasy(self):
- return self.backend.stasy
+ def talk(self):
+ return self.backend.talk
@property
def tracker(self):
@property
def wishlist(self):
return self.backend.wishlist
+
+
+class LoginHandler(BaseHandler):
+ def get(self):
+ self.render("auth/login.html")
+
+ def post(self):
+ username = self.get_argument("username")
+ password = self.get_argument("password")
+
+ if not self.login(username, password):
+ raise tornado.web.HTTPError(401)
+
+ next = self.get_argument("next", "/")
+ return self.redirect(next)
+
+
+class LogoutHandler(BaseHandler):
+ def get(self):
+ self.logout()
+
+ # Get back to the start page
+ self.redirect("/")