""" mod_python gateway to all interesting cobbler web functions Copyright 2007-2009, Red Hat, Inc Michael DeHaan This software may be freely redistributed under the terms of the GNU general public license. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. """ from mod_python import apache from mod_python import Session from mod_python import util import xmlrpclib import cgi import os from cobbler.webui import CobblerWeb import cobbler.utils as utils import yaml # PyYAML XMLRPC_SERVER = "http://127.0.0.1:25151" # FIXME: pull port from settings #======================================= class ServerProxy(xmlrpclib.ServerProxy): """ Establishes a connection from the mod_python web interface to cobblerd, which incidentally is also being proxied by Apache. """ def __init__(self, url=None): xmlrpclib.ServerProxy.__init__(self, url, allow_none=True) xmlrpc_server = ServerProxy(XMLRPC_SERVER) #======================================= def __get_user(req): """ What user are we logged in as? """ req.add_common_vars() env_vars = req.subprocess_env.copy() return env_vars["REMOTE_USER"] def __get_session(req): """ Get/Create the Apache Session Object FIXME: any reason to not use MemorySession? """ if not hasattr(req,"session"): req.session = Session.MemorySession(req) return req.session #====================================================== def handler(req): """ Right now, index serves everything. Hitting this URL means we've already cleared authn/authz but we still need to use the token for all remote requests. """ my_user = __get_user(req) my_uri = req.uri sess = __get_session(req) if not sess.has_key('cobbler_token'): # using Kerberos instead of Python Auth handler? # We need to get our own token for use with authn_passthru # which should also be configured in /etc/cobbler/modules.conf # if another auth mode is configured in modules.conf this will # most certaintly fail. try: if not os.path.exists("/var/lib/cobbler/web.ss"): apache.log_error("cannot load /var/lib/cobbler/web.ss") return apache.HTTP_UNAUTHORIZED fd = open("/var/lib/cobbler/web.ss") data = fd.read() my_pw = data fd.close() token = xmlrpc_server.login(my_user,my_pw) except Exception, e: apache.log_error(str(e)) return apache.HTTP_UNAUTHORIZED sess['cobbler_token'] = token else: token = sess['cobbler_token'] # needed? # usage later req.add_common_vars() # process form and qs data, if any fs = util.FieldStorage(req) form = {} for x in fs.keys(): form[x] = str(fs.get(x,'default')) fd = open("/etc/cobbler/settings") data = fd.read() fd.close() ydata = yaml.load(data) remote_port = ydata.get("xmlrpc_port", 25151) mode = form.get('mode','index') # instantiate a CobblerWeb object cw = CobblerWeb.CobblerWeb( apache = apache, token = token, base_url = "/cobbler/web/", mode = mode, server = "http://127.0.0.1:%s" % remote_port ) # check for a valid path/mode # handle invalid paths gracefully if mode in cw.modes(): func = getattr( cw, mode ) content = func( **form ) else: func = getattr( cw, 'error_page' ) content = func( "Invalid Mode: \"%s\"" % mode ) if content.startswith("# REDIRECT "): util.redirect(req, location=content[11:], permanent=False) else: # apache.log_error("%s:%s ... %s" % (my_user, my_uri, str(form))) req.content_type = "text/html;charset=utf-8" req.write(unicode(content).encode('utf-8')) if not content.startswith("# ERROR") and content.find("") == -1: return apache.OK else: # catch Cheetah errors and web errors return apache.HTTP_ERROR #====================================================== def authenhandler(req): """ Validates that username/password are a valid combination, but does not check access levels. """ my_pw = req.get_basic_auth_pw() my_user = req.user my_uri = req.uri try: token = xmlrpc_server.login(my_user,my_pw) except Exception, e: apache.log_error(str(e)) return apache.HTTP_UNAUTHORIZED try: ok = xmlrpc_server.check_access(token,my_uri) except Exception, e: apache.log_error(str(e)) return apache.HTTP_FORBIDDEN sess=__get_session(req) sess['cobbler_token'] = token sess.save() return apache.OK #====================================================== def accesshandler(req): """ Not using this """ return apache.OK #====================================================== def authenzhandler(req): """ Not using this """ return apache.OK