from __future__ import division
+import datetime
+import dateutil.parser
import httplib
+import ipaddr
+import logging
import time
import tornado.locale
import tornado.web
-import backend
-
-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 render_args(self):
+ def hostname(self):
+ # Remove the development prefix
+ return self.request.host.replace(".dev.", ".")
+
+ @property
+ def ssl_params(self):
return {
- "format_size" : format_size,
- "hostname" : self.request.host,
+ "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()
+
+ 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" : time.strftime("%Y"),
+ "year" : today.year,
}
+ ret.update(self.ssl_params)
+
+ return ret
def render(self, *args, **_kwargs):
kwargs = self.render_args
return ret
if static:
- return "http://static.ipfire.org%s" % ret
+ return "//static.ipfire.org%s" % ret
return ret
+ def get_remote_ip(self):
+ # Fix for clients behind a proxy that sends "X-Forwarded-For".
+ 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
+
+ return remote_ip
+
+ # Return the last IP if nothing else worked
+ return remote_ips.pop()
+
+ def get_remote_location(self):
+ if not hasattr(self, "__remote_location"):
+ remote_ip = self.get_remote_ip()
+
+ self.__remote_location = self.geoip.get_location(remote_ip)
+
+ 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
+
+ @property
+ def db(self):
+ return self.backend.db
+
@property
def advertisements(self):
- return backend.Advertisements()
+ return self.backend.advertisements
@property
def accounts(self):
- return backend.Accounts()
+ return self.backend.accounts
+
+ @property
+ def downloads(self):
+ return self.backend.downloads
+
+ @property
+ def fireinfo(self):
+ return self.backend.fireinfo
@property
- def banners(self):
- return backend.Banners()
+ def iuse(self):
+ return self.backend.iuse
@property
def memcached(self):
- return backend.Memcached()
+ return self.backend.memcache
@property
def mirrors(self):
- return backend.Mirrors()
+ return self.backend.mirrors
+
+ @property
+ def netboot(self):
+ return self.backend.netboot
@property
def news(self):
- return backend.News()
+ return self.backend.news
@property
def config(self):
- return backend.Config()
+ return self.backend.settings
@property
def releases(self):
- return backend.Releases()
+ return self.backend.releases
@property
- def banners(self):
- return backend.Banners()
+ def geoip(self):
+ return self.backend.geoip
@property
- def geoip(self):
- return backend.GeoIP()
+ def talk(self):
+ return self.backend.talk
@property
def tracker(self):
- return backend.Tracker()
+ return self.backend.tracker
@property
def planet(self):
- return backend.Planet()
+ return self.backend.planet
@property
def wishlist(self):
- return backend.Wishlist()
+ 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("/")