]> 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 2dce5836d6bff3feca35dcdbe7b9b377624be79a..6f1ec9d4cea4cd0c838e4779508a6747b450dde8 100644 (file)
@@ -2,23 +2,16 @@
 
 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
@@ -27,46 +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 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
@@ -96,58 +84,194 @@ class BaseHandler(tornado.web.RequestHandler):
                        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("/")