Note that there are some explanatory texts on larger screens.

plurals
  1. POUpgrading a web portal: CherryPy2.2 to 3.2 Issues
    primarykey
    data
    text
    <p>I am a Java guy who has inherited a web portal upgrade project that uses CherryPy2.2. There is a doLogin Module that provides the login page and a Portal module that runs all the portal functions. I need to refactor the code for CherryPy3.2.</p> <p>One problem I am having is that the old code uses a filter (an extension of basefilter) so I tried to rewrite the class and its single method as a tool. I have setup the session tool in the config and am trying to call the tool: However, it seems that no matter which hook point I try, any call to cherrypy.session yields the error that "module object has no attribute 'session'". I have looked this up online and others have said that hooking later in the request process worked for them, but not here. NO hook point works. There is apparently no session established.</p> <p>Currently, doLogin works and the login page is correctly displayed, but attempting to login produces errors, specifically the one mentioned above.</p> <p>I am providing the code for both doLogin (working) and Portal (not working) as well as Portal_OLD which is the 2.2 version. I am also providing the config file used by doLogin.</p> <p>The class of interest is SessionCheck (in Portal.py) and SessionCheckFilter (in Portal_OLD). This class has the method before_Request_Body that I am trying to make into a tool. Also in this method are calls to cherrypy.session that are throwing the error.</p> <p>I would be grateful for any pointers on how to get this coded correctly so that the old filter can run as a tool with sessions working properly.</p> <p><strong>Here is the doLogin.py module:</strong></p> <pre><code>#!/usr/bin/python import cherrypy import os import sys import time import string import urllib import subprocess import pam from datetime import datetime from pam import authenticate from cherrypy import checker from cherrypy import tools from cherrypy import log from cherrypy.lib import sessions from cherrypy.lib.sessions import Session from Cheetah.Template import Template from Login import Login from Error import Error from Defs import Defs VERSION_doLogin = "0.20" # Default daemon parameters. UMASK = 0 # File mode creation mask. MAXFD = 1024 # Default max num of available file descriptors. REDIRECT_TO = "/var/log/doLogin.log" # Redirect standard I/O file descriptors. WORKDIR = "." # Default working directory. # Port Management def DebugWrite(stmt): dbug = open("/tmp/debug.txt","ab") dbug.write("[%s] DEBUG: %s\n" % (str(datetime.now()),stmt)) return -1 def ChoosePort(path): CHILD_PORT_MIN = 8001 CHILD_PORT_MAX = 8099 for port in range(CHILD_PORT_MIN, CHILD_PORT_MAX + 1): pfile = "%s/%d" % (path, port) if not os.path.isfile(pfile): return port return 0 def LockPort(path, port, pid): pfile = "%s/%d" % (path, port) pidstr = "%s" % (pid) if not os.path.isfile(pfile): try: output = open(pfile, 'w') output.write(pidstr) output.close() except: pass else: return 0 return -1 class Auth: def index(self): cherrypy.session["unexpired"]="yes" self.tmpl = Login() return self.tmpl.respond() index.exposed = True def default(self, *args): self.tmpl = Error() self.tmpl.title = "Error Page" self.tmpl.content = "You have entered an invalid URL" return self.tmpl.respond() default.exposed = True def doLogin(self, userid="invalid", password="blank", Submit="None"): port_path = "/users/gportal/%s-ports" % Defs().getUrc("PRIV_NAME") if userid == "": userid = "invalid" if password == "": password = "blank" self.tmpl = Error() success = authenticate(userid, password, service='password-auth') if success == True: self.tmpl = Error() cherrypy.session["Auth"]='yes' portal_path = "%s/Portal.py" % (Defs().getUrc("PORTAL_ROOT")) try: ret_code=subprocess.call(["/usr/bin/sudo", "-l", "-u", userid, portal_path]) if ret_code != 0: self.tmpl.content = "User %s is not authorized to use the %s Portal!" % (userid, Defs().getUrc("CLUSTER")) self.tmpl.title = "Unauthorized User" return self.tmpl.respond() except OSError, e: self.tmpl.content = "Execution failed: %d (%s)" % (e.errno, e.strerror) self.tmpl.title = "Execution failed" return self.tmpl.respond() port = ChoosePort(port_path) try: pid = os.fork() if pid &gt; 0: os.wait() time.sleep(2) user_url = "%s/%d/" % (Defs().getUrc("URL"), port) raise cherrypy.HTTPRedirect(user_url, 302) elif pid == 0: pid = os.fork() if pid &gt; 0: LockPort(port_path, port, pid) os._exit(0) os.setsid() portstr = "%s" % (port) os.execve("/usr/bin/sudo", ["sudo", "-E", "-u", userid, portal_path], {"port":portstr, "session_id":cherrypy.session.generate_id()}) except OSError, e: self.tmpl.content = "fork failed: %d (%s)" % (e.errno, e.strerror) return self.tmpl.respond() else: self.tmpl = Error() self.tmpl.content = "Authorization Denied: Invalid username/password pair" self.tmpl.title = "Authorization Failed" return self.tmpl.respond() doLogin.exposed = True ################################################################################### # Main ################################################################################### if __name__ == '__main__': # Let's be a daemon. try: pid = os.fork() except OSError, e: raise Exception, "%s [%d]" % (e.strerror, e.errno) if (pid == 0): # The first child. os.setsid() try: pid = os.fork() # Fork a second child. except OSError, e: raise Exception, "%s [%d]" % (e.strerror, e.errno) if (pid == 0): # The second child. # os.chdir(WORKDIR) os.umask(UMASK) else: os._exit(0) # Exit parent (the first child) of the second child. else: os._exit(0) # Exit parent of the first child. # Iterate through and close all file descriptors. maxfd = MAXFD for fd in range(0, maxfd): try: os.close(fd) except OSError: # ERROR, fd wasn't open to begin with (ignored) pass # Redirect Standard input (and output and error below) os.open(REDIRECT_TO, os.O_RDWR) # standard input (0) # Duplicate standard input to standard output and standard error. os.dup2(0, 1) # standard output (1) os.dup2(0, 2) # standard error (2) # Now we should be a daemon! ###################################################################### # Let's do some work. ###################################################################### cherrypy.checker.on='True' cherrypy.log.error_log.setLevel('DEBUG') cherrypy.log.time() cherrypy.config.update('/etc/httpd/htdocs/portal/conf/portal.conf') cherrypy.tree.mount(Auth(), '', '/etc/httpd/htdocs/portal/conf/portal.conf') cherrypy.quickstart(Auth(), '', '/etc/httpd/htdocs/portal/conf/portal.conf') </code></pre> <p><strong>Here is the Portal.py module:</strong></p> <pre><code> #!/usr/bin/python VERSION_Portal = "0.30" import posix import pwd import os import os.path import string import datetime import cPickle as pickle import cherrypy from cherrypy import tools from cherrypy.lib import sessions # from cherrypy.lib.filter import basefilter ### NO filters in 3.2 from cherrypy.lib.sessions import Session from Cheetah.Template import Template from Welcome import Welcome from Error import Error from Content import Content from FileDel import FileDelete from FileList import FileList from Down import FileDownload from Up import FileUpload from FileBrowser import FileBrowser from FileEdit import FileEdit from OpenSource import OpenSource from Defs import Defs from PBS import PbsNodes, Qdel, Qstat, Qsub from doLogin import Auth class SessionCheck: _cp_config = {'tools.sessions.on': True, 'tools.sessions.storage_type': "file", 'tools.sessions.storage_path': "/users/gportal/sessions/"} def beforeRequestBody(): sid = cherrypy.session.get('id') cherrypy.session["unexpired"]="yes" cherrypy.session["Auth"]="yes" session_id=os.environ["session_id"] if session_id != sid: try: str_val = Defs().getUrc("URL") + '/portal/' raise cherrypy.HTTPRedirect(str_val, 302) finally: storage_path = cherrypy.config.get('tools.sessions.storage_path') now = datetime.datetime.now() fname = "session-%s" % session_id file_path = os.path.join(storage_path, fname) try: f = open(file_path, "rb") data, expiration_time = pickle.load(f) f.close() if expiration_time &lt; now: # Session expired: stopping os.remove(fname) cherrypy.server.stop() os._exit(0) except: # We can't access the file ... so stop the server cherrypy.server.stop() os._exit(0) cherrypy.tools.beforeRequestBody = cherrypy.Tool('before_request_body', beforeRequestBody(), name=None, priority=100) cherrypy.request.hooks.attach('before_request_body', beforeRequestBody, failsafe=True, priority=100) @cherrypy.tools.beforeRequestBody() class Portal: def index(self): self.urc_quota = Defs().value('QUOTA_SCRIPT') self.tmpl = Welcome() self.tmpl.port = string.atoi(os.environ['port']) self.tmpl.username=uname # Username determined below. child = os.popen(self.urc_quota) self.tmpl.htmlval = child.read() self.tmpl.content = " " return self.tmpl.respond() index.exposed = True def default(self, *args): self.tmpl = Error() self.tmpl.title = "Error Page" self.tmpl.content = "You have entered an invalid URL" return self.tmpl.respond() default.exposed = True def OpenSource(self): self.tmpl = OpenSource() self.tmpl.port = string.atoi(os.environ['port']) self.tmpl.title = "Open Source Development" self.tmpl.name = " " return self.tmpl.respond() OpenSource.exposed = True def Logout(self): try: str_val = Defs().getUrc("URL") + '/portal/' raise cherrypy.HTTPRedirect(str_val, 302) finally: cherrypy.server.stop() Logout.exposed = True # MAIN if __name__ == '__main__': # Gather/set some user info for the portal server process pwinfo=pwd.getpwuid(posix.getuid()) ulogin=pwinfo[0] uname=pwinfo[4] # used in greeting above uhome=pwinfo[5] sess_path = "%s/.gportal/" % uhome log_path = "%s/session.log" % sess_path # Set Cherrypy config options # cherrypy.config.update('conf/portal.conf') global_settings = { 'tools.sessions.on': True, 'tools.sessions.storage_type': "file", 'tools.sessions.storage_path': sess_path, 'tools.sessions.timeout': 60, 'tools.sessions.clean_freq': 5, 'tools.beforeRequestBody.on': True, 'server.log_file': log_path, 'server.socket_port':string.atoi(os.environ['port']) } cherrypy.config.update(global_settings) # Change to user's home directory os.chdir(uhome) # Make sure ".gportal" directory exists if (not os.path.isdir(".gportal")): os.mkdir(".gportal", 0755) # Handlers cherrypy.root = Portal() cherrypy.root.uploadfile = FileUpload() cherrypy.root.downloadfile = FileDownload() cherrypy.root.listfiles = FileList() cherrypy.root.deletefile = FileDelete() cherrypy.root.filebrowser = FileBrowser() cherrypy.root.editfile = FileEdit() cherrypy.root.pbsnodes = PbsNodes() cherrypy.root.qdel = Qdel() cherrypy.root.qstat = Qstat() cherrypy.root.qsub = Qsub() cherrypy.root.error = Error() cherrypy.quickstart(Portal()) </code></pre> <p><strong>Here is the Portal_OLD module:</strong></p> <pre><code>#!/usr/bin/python VERSION_Portal = "0.30" import posix import pwd import os import os.path import string import datetime import cPickle as pickle import cherrypy from Cheetah.Template import Template from Welcome import Welcome from Error import Error from Content import Content from FileDel import FileDelete from FileList import FileList from Down import FileDownload from Up import FileUpload from FileBrowser import FileBrowser from FileEdit import FileEdit from OpenSource import OpenSource from cherrypy.lib.filter import basefilter from Defs import Defs from PBS import PbsNodes, Qdel, Qstat, Qsub class SessionCheckFilter(basefilter.BaseFilter): def beforeRequestBody(self): session_id=os.environ["session_id"] if session_id != cherrypy.session["_id"]: try: str_val = Defs().getUrc("URL") + '/portal/' raise cherrypy.HTTPRedirect(str_val, 302) finally: storage_path = cherrypy.config.get('session_filter.storage_path') now = datetime.datetime.now() fname = "session-%s" % session_id file_path = os.path.join(storage_path, fname) try: f = open(file_path, "rb") data, expiration_time = pickle.load(f) f.close() if expiration_time &lt; now: # Session expired: stopping os.remove(fname) cherrypy.server.stop() os._exit(0) except: # We can't access the file ... so stop the server cherrypy.server.stop() os._exit(0) class Portal: _cpFilterList = [ SessionCheckFilter() ] def index(self): self.urc_quota = Defs().value('QUOTA_SCRIPT') self.tmpl = Welcome() self.tmpl.port = string.atoi(os.environ['port']) self.tmpl.username=uname # Username determined below. child = os.popen(self.urc_quota) self.tmpl.htmlval = child.read() self.tmpl.content = " " return self.tmpl.respond() index.exposed = True def default(self, *args): self.tmpl = Error() self.tmpl.title = "Error Page" self.tmpl.content = "You have entered an invalid URL" return self.tmpl.respond() default.exposed = True def OpenSource(self): self.tmpl = OpenSource() self.tmpl.port = string.atoi(os.environ['port']) self.tmpl.title = "Open Source Development" self.tmpl.name = " " return self.tmpl.respond() OpenSource.exposed = True def Logout(self): try: str_val = Defs().getUrc("URL") + '/portal/' raise cherrypy.HTTPRedirect(str_val, 302) finally: cherrypy.server.stop() Logout.exposed = True # MAIN if __name__ == '__main__': # Gather/set some user info for the portal server process pwinfo=pwd.getpwuid(posix.getuid()) ulogin=pwinfo[0] uname=pwinfo[4] # used in greeting above uhome=pwinfo[5] sess_path = "%s/.gportal/" % uhome log_path = "%s/session.log" % sess_path # Set Cherrypy config options cherrypy.config.update(file = 'conf/portal.conf') cherrypy.config.update({'session_filter.on': True}) cherrypy.config.update({'session_filter.timeout': 60}) cherrypy.config.update({'session_filter.clean_up_delay': 5}) cherrypy.config.update({'session_filter.storage_type': "File"}) cherrypy.config.update({'session_filter.storage_path': sess_path}) cherrypy.config.update({'server.log_file': log_path}) cherrypy.config.update({'server.socketPort':string.atoi(os.environ['port'])}) # Change to user's home directory os.chdir(uhome) # Make sure ".gportal" directory exists if (not os.path.isdir(".gportal")): os.mkdir(".gportal", 0755) # Handlers cherrypy.root = Portal() cherrypy.root.uploadfile = FileUpload() cherrypy.root.downloadfile = FileDownload() cherrypy.root.listfiles = FileList() cherrypy.root.deletefile = FileDelete() cherrypy.root.filebrowser = FileBrowser() cherrypy.root.editfile = FileEdit() cherrypy.root.pbsnodes = PbsNodes() cherrypy.root.qdel = Qdel() cherrypy.root.qstat = Qstat() cherrypy.root.qsub = Qsub() cherrypy.root.error = Error() cherrypy.server.start() </code></pre> <p>Here is the config file (in part):</p> <pre><code># Version 0.6 [global] server.socket_port = 8080 server.threadPool = 10 server.environment = "production" server.showTracebacks = True server.logToScreen = True server.log_file = "/var/log/doLogin.log" [/] tools.staticdir.on = True tools.staticfile.on = True tools.staticdir.root = "/etc/httpd/htdocs/portal/" tools.staticfile.root = "/etc/httpd/htdocs/portal/" tools.staticdir.on = True tools.staticfile.on=True [/img] tools.staticdir.on = True tools.staticdir.dir "img" [/filebrowser.css] tools.staticfile.on=True tools.staticfile.filename="filebrowser.css" [/style.css] tools.staticfile.on=True tools.staticfile.filename="style.css" </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload