]> git.ipfire.org Git - people/shoehn/ipfire.org.git/blobdiff - webapp/handlers_base.py
netboot: Allow booting multiple architectures
[people/shoehn/ipfire.org.git] / webapp / handlers_base.py
index ddf19129adc42b95308226408802b19862af7a46..6f1ec9d4cea4cd0c838e4779508a6747b450dde8 100644 (file)
@@ -2,22 +2,16 @@
 
 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
@@ -26,48 +20,41 @@ class BaseHandler(tornado.web.RequestHandler):
                # 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
@@ -93,18 +80,34 @@ class BaseHandler(tornado.web.RequestHandler):
        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"):
@@ -114,6 +117,70 @@ class BaseHandler(tornado.web.RequestHandler):
 
                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
@@ -134,6 +201,10 @@ class BaseHandler(tornado.web.RequestHandler):
        def downloads(self):
                return self.backend.downloads
 
+       @property
+       def fireinfo(self):
+               return self.backend.fireinfo
+
        @property
        def iuse(self):
                return self.backend.iuse
@@ -167,8 +238,8 @@ class BaseHandler(tornado.web.RequestHandler):
                return self.backend.geoip
 
        @property
-       def stasy(self):
-               return self.backend.stasy
+       def talk(self):
+               return self.backend.talk
 
        @property
        def tracker(self):
@@ -181,3 +252,26 @@ class BaseHandler(tornado.web.RequestHandler):
        @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("/")