""" mod_python gateway to all interesting cobbler web functions Copyright 2007, 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 XMLRPC_SERVER = "http://127.0.0.1:25152" # was http://127.0.0.1/cobbler_api_rw" #======================================= 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? 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')) # instantiate a CobblerWeb object cw = CobblerWeb.CobblerWeb( apache = apache, token = token, base_url = "/cobbler/web/", server = "http://127.0.0.1/cobbler_api_rw" ) # check for a valid path/mode # handle invalid paths gracefully mode = form.get('mode','index') if mode in cw.modes(): func = getattr( cw, mode ) content = func( **form ) else: func = getattr( cw, 'error_page' ) content = func( "Invalid Mode: \"%s\"" % mode ) # 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')) return apache.OK #====================================================== 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