def apath(path='', r=None): """ Builds a path inside an application folder Parameters ---------- path: path within the application folder r: the global request object """ opath = up(r.folder) while path[:3] == '../': (opath, path) = (up(opath), path[3:]) return os.path.join(opath, path).replace('\\', '/')
def renew(self, clear_session=False): if clear_session: self.clear() request = current.request response = current.response session = response.session masterapp = response.session_masterapp cookies = request.cookies if response.session_storage_type == 'cookie': return # if the session goes in file if response.session_storage_type == 'file': self._close(response) uuid = web2py_uuid() response.session_id = '%s-%s' % (response.session_client, uuid) separate = (lambda s: s[ -2:]) if session and response.session_id[2:3] == "/" else None if separate: prefix = separate(response.session_id) response.session_id = '%s/%s' % \ (prefix, response.session_id) response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) response.session_new = True # else the session goes in db elif response.session_storage_type == 'db': table = response.session_db_table # verify that session_id exists if response.session_file: self._close(response) if response.session_new: return # Get session data out of the database if response.session_id is None: return (record_id, sep, unique_key) = response.session_id.partition(':') if record_id.isdigit() and long(record_id) > 1: new_unique_key = web2py_uuid() row = table(record_id) if row and row.unique_key == unique_key: table._db(table.id == record_id).update( unique_key=new_unique_key) else: record_id = None if record_id: response.session_id = '%s:%s' % (record_id, unique_key) response.session_db_record_id = record_id response.session_db_unique_key = new_unique_key else: response.session_new = True
def renew(self, clear_session=False): if clear_session: self.clear() request = current.request response = current.response session = response.session masterapp = response.session_masterapp cookies = request.cookies if response.session_storage_type == 'cookie': return # if the session goes in file if response.session_storage_type == 'file': self._close(response) uuid = web2py_uuid() response.session_id = '%s-%s' % (response.session_client, uuid) separate = (lambda s: s[-2:]) if session and response.session_id[2:3]=="/" else None if separate: prefix = separate(response.session_id) response.session_id = '%s/%s' % \ (prefix, response.session_id) response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) response.session_new = True # else the session goes in db elif response.session_storage_type == 'db': table = response.session_db_table # verify that session_id exists if response.session_file: self._close(response) if response.session_new: return # Get session data out of the database if response.session_id is None: return (record_id, sep, unique_key) = response.session_id.partition(':') if record_id.isdigit() and long(record_id)>1: new_unique_key = web2py_uuid() row = table(record_id) if row and row.unique_key==unique_key: row.update_record(unique_key=new_unique_key) else: row = None else: row = None if row: response.session_id = '%s:%s' % (record_id, unique_key) response.session_db_record_id = record_id response.session_db_unique_key = new_unique_key else: response.session_new = True
def web2py_windows_service_handler(argv=None, opt_file='options'): path = os.path.dirname(__file__) classstring = os.path.normpath(os.path.join(up(path), 'gluon.winservice.Web2pyService')) if opt_file: Web2pyService._exe_args_ = opt_file win32serviceutil.HandleCommandLine(Web2pyService, serviceClassString=classstring, argv=['', 'install']) win32serviceutil.HandleCommandLine(Web2pyService, serviceClassString=classstring, argv=argv)
def web2py_windows_service_handler(argv=None, opt_file="options"): path = os.path.dirname(__file__) web2py_path = up(path) if web2py_path.endswith(".zip"): # in case bianry distro 'library.zip' web2py_path = os.path.dirname(web2py_path) os.chdir(web2py_path) classstring = os.path.normpath(os.path.join(web2py_path, "gluon.winservice.Web2pyService")) if opt_file: Web2pyService._exe_args_ = opt_file win32serviceutil.HandleCommandLine(Web2pyService, serviceClassString=classstring, argv=["", "install"]) win32serviceutil.HandleCommandLine(Web2pyService, serviceClassString=classstring, argv=argv)
def web2py_windows_service_handler(argv=None, opt_file='options'): path = os.path.dirname(__file__) classstring = os.path.normpath( os.path.join(up(path), 'gluon.winservice.Web2pyService')) if opt_file: Web2pyService._exe_args_ = opt_file win32serviceutil.HandleCommandLine(Web2pyService, serviceClassString=classstring, argv=['', 'install']) win32serviceutil.HandleCommandLine(Web2pyService, serviceClassString=classstring, argv=argv)
def register_service_handler(argv=None, opt_file='options', cls=Web2pyService): path = os.path.dirname(__file__) web2py_path = up(path) if web2py_path.endswith('.zip'): # in case bianry distro 'library.zip' web2py_path = os.path.dirname(web2py_path) os.chdir(web2py_path) classstring = os.path.normpath( os.path.join(web2py_path, 'gluon.winservice.'+cls.__name__)) if opt_file: cls._exe_args_ = opt_file win32serviceutil.HandleCommandLine( cls, serviceClassString=classstring, argv=['', 'install']) win32serviceutil.HandleCommandLine( cls, serviceClassString=classstring, argv=argv)
def web2py_windows_service_handler(argv=None, opt_file='options'): path = os.path.dirname(__file__) web2py_path = up(path) if web2py_path.endswith('.zip'): # in case bianry distro 'library.zip' web2py_path = os.path.dirname(web2py_path) os.chdir(web2py_path) classstring = os.path.normpath( os.path.join(web2py_path, 'gluon.winservice.Web2pyService')) if opt_file: Web2pyService._exe_args_ = opt_file win32serviceutil.HandleCommandLine(Web2pyService, serviceClassString=classstring, argv=['', 'install']) win32serviceutil.HandleCommandLine(Web2pyService, serviceClassString=classstring, argv=argv)
def register_service_handler(argv=None, opt_file="options", cls=Web2pyService): """ This is a CCP extension to allow different services with different names to run This requires service_name and service_display_name in your options_svcname.py file """ path = os.path.dirname(__file__) web2py_path = up(path) if web2py_path.endswith(".zip"): # in case bianry distro 'library.zip' web2py_path = os.path.dirname(web2py_path) os.chdir(web2py_path) classstring = os.path.normpath(os.path.join(web2py_path, "gluon.winservice." + cls.__name__)) if not opt_file: raise Exception("You must supply an option file with the -L argument") options = __import__(opt_file, [], [], "") try: cls._svc_name_ = options.service_name cls._svc_display_name_ = options.service_display_name except AttributeError, e: raise AttributeError("Missing service_name and service_display_name in %s" % opt_file)
def register_service_handler(argv=None, opt_file='options', cls=Web2pyService): """ This is a CCP extension to allow different services with different names to run This requires service_name and service_display_name in your options_svcname.py file """ path = os.path.dirname(__file__) web2py_path = up(path) if web2py_path.endswith('.zip'): # in case bianry distro 'library.zip' web2py_path = os.path.dirname(web2py_path) os.chdir(web2py_path) classstring = os.path.normpath( os.path.join(web2py_path, 'gluon.winservice.' + cls.__name__)) if not opt_file: raise Exception("You must supply an option file with the -L argument") options = __import__(opt_file, [], [], '') try: cls._svc_name_ = options.service_name cls._svc_display_name_ = options.service_display_name except AttributeError, e: raise AttributeError( "Missing service_name and service_display_name in %s" % opt_file)
def connect( self, request, response, db=None, tablename="web2py_session", masterapp=None, migrate=True, separate=None, check_client=False, cookie_key=None, ): """ separate can be separate=lambda(session_name): session_name[-2:] and it is used to determine a session prefix. separate can be True and it is set to session_name[-2:] """ if separate == True: separate = lambda session_name: session_name[-2:] self._unlock(response) if not masterapp: masterapp = request.application response.session_id_name = "session_id_%s" % masterapp.lower() # Load session data from cookie if cookie_key: response.session_cookie_key = cookie_key response.session_cookie_key2 = hashlib.md5(cookie_key).digest() cookie_name = request.application.lower() + "_session_data" response.session_cookie_name = cookie_name if cookie_data in request.cookies: cookie_value = request.cookies[cookie_name].value cookie_parts = cookie_value.split(":") enc = cookie_parts[2] cipher = AES.new(cookie_key) decrypted = cipher.decrypt(base64.b64decode(enc)).rstrip("{") check = hmac.new(response.session_cookie_key2, enc).hexdigest() if cookie_parts[0] == check: session_data = cPickle.loads(decrypted) self.update(session_data) else: return if not db: if global_settings.db_sessions is True or masterapp in global_settings.db_sessions: return response.session_new = False client = request.client and request.client.replace(":", ".") if response.session_id_name in request.cookies: response.session_id = request.cookies[response.session_id_name].value if regex_session_id.match(response.session_id): response.session_filename = os.path.join( up(request.folder), masterapp, "sessions", response.session_id ) else: response.session_id = None if response.session_id: try: response.session_file = open(response.session_filename, "rb+") try: portalocker.lock(response.session_file, portalocker.LOCK_EX) response.session_locked = True self.update(cPickle.load(response.session_file)) response.session_file.seek(0) oc = response.session_filename.split("/")[-1].split("-")[0] if check_client and client != oc: raise Exception, "cookie attack" finally: pass # This causes admin login to break. Must find out why. # self._close(response) except: response.session_id = None if not response.session_id: uuid = web2py_uuid() response.session_id = "%s-%s" % (client, uuid) if separate: prefix = separate(response.session_id) response.session_id = "%s/%s" % (prefix, response.session_id) response.session_filename = os.path.join(up(request.folder), masterapp, "sessions", response.session_id) response.session_new = True else: if global_settings.db_sessions is not True: global_settings.db_sessions.add(masterapp) response.session_db = True if response.session_file: self._close(response) if settings.global_settings.web2py_runtime_gae: # in principle this could work without GAE request.tickets_db = db if masterapp == request.application: table_migrate = migrate else: table_migrate = False tname = tablename + "_" + masterapp table = db.get(tname, None) if table is None: table = db.define_table( tname, db.Field("locked", "boolean", default=False), db.Field("client_ip", length=64), db.Field("created_datetime", "datetime", default=request.now), db.Field("modified_datetime", "datetime"), db.Field("unique_key", length=64), db.Field("session_data", "blob"), migrate=table_migrate, ) try: # Get session data out of the database # Key comes from the cookie key = request.cookies[response.session_id_name].value (record_id, unique_key) = key.split(":") if record_id == "0": raise Exception, "record_id == 0" # Select from database. rows = db(table.id == record_id).select() # Make sure the session data exists in the database if len(rows) == 0 or rows[0].unique_key != unique_key: raise Exception, "No record" # rows[0].update_record(locked=True) # Unpickle the data session_data = cPickle.loads(rows[0].session_data) self.update(session_data) except Exception: record_id = None unique_key = web2py_uuid() session_data = {} response._dbtable_and_field = (response.session_id_name, table, record_id, unique_key) response.session_id = "%s:%s" % (record_id, unique_key) response.cookies[response.session_id_name] = response.session_id response.cookies[response.session_id_name]["path"] = "/" self.__hash = hashlib.md5(str(self)).digest() if self.flash: (response.flash, self.flash) = (self.flash, None)
def connect( self, request, response, db=None, tablename='web2py_session', masterapp=None, migrate=True, separate = None, check_client=False, cookie_key=None, ): """ separate can be separate=lambda(session_name): session_name[-2:] and it is used to determine a session prefix. separate can be True and it is set to session_name[-2:] """ if separate == True: separate = lambda session_name: session_name[-2:] self._unlock(response) if not masterapp: masterapp = request.application response.session_id_name = 'session_id_%s' % masterapp.lower() # Load session data from cookie cookies = request.cookies if cookie_key: response.session_cookie_key = cookie_key response.session_cookie_key2 = hashlib.md5(cookie_key).digest() cookie_name = masterapp.lower()+'_session_data' response.session_cookie_name = cookie_name if cookie_name in cookies: cookie_value = cookies[cookie_name].value cookie_parts = cookie_value.split(":") enc = cookie_parts[2] cipher = AES.new(cookie_key) decrypted = cipher.decrypt(base64.b64decode(enc)).rstrip('{') check = hmac.new(response.session_cookie_key2,enc).hexdigest() if cookie_parts[0] == check: session_data = cPickle.loads(decrypted) self.update(session_data) else: return if not db: if global_settings.db_sessions is True \ or masterapp in global_settings.db_sessions: return response.session_new = False client = request.client and request.client.replace(':', '.') if response.session_id_name in cookies: response.session_id = \ cookies[response.session_id_name].value if regex_session_id.match(response.session_id): response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) else: response.session_id = None if response.session_id: try: response.session_file = \ open(response.session_filename, 'rb+') try: portalocker.lock(response.session_file, portalocker.LOCK_EX) response.session_locked = True self.update(cPickle.load(response.session_file)) response.session_file.seek(0) oc = response.session_filename.split('/')[-1]\ .split('-')[0] if check_client and client!=oc: raise Exception, "cookie attack" finally: pass #This causes admin login to break. Must find out why. #self._close(response) except: response.session_id = None if not response.session_id: uuid = web2py_uuid() response.session_id = '%s-%s' % (client, uuid) if separate: prefix = separate(response.session_id) response.session_id = '%s/%s' % \ (prefix,response.session_id) response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) response.session_new = True else: if global_settings.db_sessions is not True: global_settings.db_sessions.add(masterapp) response.session_db = True if response.session_file: self._close(response) if settings.global_settings.web2py_runtime_gae: # in principle this could work without GAE request.tickets_db = db if masterapp == request.application: table_migrate = migrate else: table_migrate = False tname = tablename + '_' + masterapp table = db.get(tname, None) Field = db.Field if table is None: db.define_table( tname, Field('locked', 'boolean', default=False), Field('client_ip', length=64), Field('created_datetime', 'datetime', default=request.now), Field('modified_datetime', 'datetime'), Field('unique_key', length=64), Field('session_data', 'blob'), migrate=table_migrate, ) table = db[tname] # to allow for lazy table try: # Get session data out of the database # Key comes from the cookie key = cookies[response.session_id_name].value (record_id, unique_key) = key.split(':') if record_id == '0': raise Exception, 'record_id == 0' # Select from database rows = db(table.id == record_id).select() # Make sure the session data exists in the database if len(rows) == 0 or rows[0].unique_key != unique_key: raise Exception, 'No record' # rows[0].update_record(locked=True) # Unpickle the data session_data = cPickle.loads(rows[0].session_data) self.update(session_data) except Exception: record_id = None unique_key = web2py_uuid() session_data = {} response._dbtable_and_field = \ (response.session_id_name, table, record_id, unique_key) response.session_id = '%s:%s' % (record_id, unique_key) rcookies = response.cookies rcookies[response.session_id_name] = response.session_id rcookies[response.session_id_name]['path'] = '/' self.__hash = hashlib.md5(str(self)).digest() if self.flash: (response.flash, self.flash) = (self.flash, None)
def connect( self, request=None, response=None, db=None, tablename="web2py_session", masterapp=None, migrate=True, separate=None, check_client=False, cookie_key=None, cookie_expires=None, compression_level=None, ): """ separate can be separate=lambda(session_name): session_name[-2:] and it is used to determine a session prefix. separate can be True and it is set to session_name[-2:] """ if request is None: request = current.request if response is None: response = current.response if separate is True: separate = lambda session_name: session_name[-2:] self._unlock(response) if not masterapp: masterapp = request.application response.session_id_name = "session_id_%s" % masterapp.lower() response.session_data_name = "session_data_%s" % masterapp.lower() response.session_cookie_expires = cookie_expires # Load session data from cookie cookies = request.cookies # check if there is a session_id in cookies if response.session_id_name in cookies: response.session_id = cookies[response.session_id_name].value else: response.session_id = None # check if there is session data in cookies if response.session_data_name in cookies: session_cookie_data = cookies[response.session_data_name].value else: session_cookie_data = None # if we are supposed to use cookie based session data if cookie_key: response.session_storage_type = "cookie" response.session_cookie_key = cookie_key response.session_cookie_compression_level = compression_level if session_cookie_data: data = secure_loads(session_cookie_data, cookie_key, compression_level=compression_level) if data: self.update(data) # else if we are supposed to use file based sessions elif not db: response.session_storage_type = "file" if global_settings.db_sessions is True or masterapp in global_settings.db_sessions: return response.session_new = False client = request.client and request.client.replace(":", ".") if response.session_id: if regex_session_id.match(response.session_id): response.session_filename = os.path.join( up(request.folder), masterapp, "sessions", response.session_id ) else: response.session_id = None # do not try load the data from file is these was data in cookie if response.session_id and not session_cookie_data: # os.path.exists(response.session_filename): try: response.session_file = open(response.session_filename, "rb+") try: portalocker.lock(response.session_file, portalocker.LOCK_EX) response.session_locked = True self.update(cPickle.load(response.session_file)) response.session_file.seek(0) oc = response.session_filename.split("/")[-1].split("-")[0] if check_client and client != oc: raise Exception("cookie attack") except: response.session_id = None finally: pass # This causes admin login to break. Must find out why. # self._close(response) except: response.session_file = None if not response.session_id: uuid = web2py_uuid() response.session_id = "%s-%s" % (client, uuid) if separate: prefix = separate(response.session_id) response.session_id = "%s/%s" % (prefix, response.session_id) response.session_filename = os.path.join(up(request.folder), masterapp, "sessions", response.session_id) response.session_new = True # else the session goes in db else: response.session_storage_type = "db" if global_settings.db_sessions is not True: global_settings.db_sessions.add(masterapp) if response.session_file: self._close(response) if settings.global_settings.web2py_runtime_gae: # in principle this could work without GAE request.tickets_db = db if masterapp == request.application: table_migrate = migrate else: table_migrate = False tname = tablename + "_" + masterapp table = db.get(tname, None) Field = db.Field if table is None: db.define_table( tname, Field("locked", "boolean", default=False), Field("client_ip", length=64), Field("created_datetime", "datetime", default=request.now), Field("modified_datetime", "datetime"), Field("unique_key", length=64), Field("session_data", "blob"), migrate=table_migrate, ) table = db[tname] # to allow for lazy table try: # Get session data out of the database (record_id, unique_key) = response.session_id.split(":") if record_id == "0": raise Exception("record_id == 0") # Select from database if not session_cookie_data: rows = db(table.id == record_id).select() # Make sure the session data exists in the database if len(rows) == 0 or rows[0].unique_key != unique_key: raise Exception("No record") # rows[0].update_record(locked=True) # Unpickle the data session_data = cPickle.loads(rows[0].session_data) self.update(session_data) except Exception: record_id = None unique_key = web2py_uuid() session_data = {} response.session_id = "%s:%s" % (record_id, unique_key) response.session_db_table = table response.session_db_record_id = record_id response.session_db_unique_key = unique_key # keep tablename parameter for use in session renew response.session_table_name = tablename rcookies = response.cookies rcookies[response.session_id_name] = response.session_id rcookies[response.session_id_name]["path"] = "/" if cookie_expires: rcookies[response.session_id_name]["expires"] = cookie_expires.strftime(FMT) # if not cookie_key, but session_data_name in cookies # expire session_data_name from cookies if session_cookie_data: rcookies[response.session_data_name] = "expired" rcookies[response.session_data_name]["path"] = "/" rcookies[response.session_data_name]["expires"] = PAST if self.flash: (response.flash, self.flash) = (self.flash, None)
def connect(self, request, response, db=None, tablename="web2py_session", masterapp=None, migrate=True): self._unlock(response) if not masterapp: masterapp = request.application response.session_id_name = "session_id_%s" % masterapp if not db: if response.session_id_name in request.cookies: response.session_id = request.cookies[response.session_id_name].value if regex_session_id.match(response.session_id): response.session_filename = os.path.join( up(request.folder), masterapp, "sessions", response.session_id ) else: response.session_id = None if response.session_id: try: response.session_file = open(response.session_filename, "rb+") portalocker.lock(response.session_file, portalocker.LOCK_EX) self.update(cPickle.load(response.session_file)) response.session_file.seek(0) except: self._unlock(response) response.session_id = None if not response.session_id: response.session_id = "%s-%s" % (request.client.replace(":", "-").replace(".", "-"), uuid.uuid4()) response.session_filename = os.path.join(up(request.folder), masterapp, "sessions", response.session_id) response.session_new = True else: if settings.web2py_runtime_gae: # in principle this could work without GAE request.tickets_db = db if masterapp == request.application: table_migrate = migrate else: table_migrate = False tname = tablename + "_" + masterapp table = db.get(tname, None) if table is None: table = db.define_table( tname, db.Field("locked", "boolean", default=False), db.Field("client_ip", length=64), db.Field("created_datetime", "datetime", default=request.now), db.Field("modified_datetime", "datetime"), db.Field("unique_key", length=64), db.Field("session_data", "blob"), migrate=table_migrate, ) try: key = request.cookies[response.session_id_name].value (record_id, unique_key) = key.split(":") if record_id == "0": raise Exception, "record_id == 0" rows = db(table.id == record_id).select() if len(rows) == 0 or rows[0].unique_key != unique_key: raise Exception, "No record" # rows[0].update_record(locked=True) session_data = cPickle.loads(rows[0].session_data) self.update(session_data) except Exception: record_id = None unique_key = str(uuid.uuid4()) session_data = {} response._dbtable_and_field = (response.session_id_name, table, record_id, unique_key) response.session_id = "%s:%s" % (record_id, unique_key) response.cookies[response.session_id_name] = response.session_id response.cookies[response.session_id_name]["path"] = "/" if self.flash: (response.flash, self.flash) = (self.flash, None)
def connect(self, request=None, response=None, db=None, tablename='web2py_session', masterapp=None, migrate=True, separate=None, check_client=False, cookie_key=None, cookie_expires=None, compression_level=None): """ separate can be separate=lambda(session_name): session_name[-2:] and it is used to determine a session prefix. separate can be True and it is set to session_name[-2:] """ if request is None: request = current.request if response is None: response = current.response if separate is True: separate = lambda session_name: session_name[-2:] self._unlock(response) if not masterapp: masterapp = request.application response.session_id_name = 'session_id_%s' % masterapp.lower() response.session_data_name = 'session_data_%s' % masterapp.lower() response.session_cookie_expires = cookie_expires # Load session data from cookie cookies = request.cookies # check if there is a session_id in cookies if response.session_id_name in cookies: response.session_id = \ cookies[response.session_id_name].value else: response.session_id = None # check if there is session data in cookies if response.session_data_name in cookies: session_cookie_data = cookies[response.session_data_name].value else: session_cookie_data = None # if we are supposed to use cookie based session data if cookie_key: response.session_storage_type = 'cookie' response.session_cookie_key = cookie_key response.session_cookie_compression_level = compression_level if session_cookie_data: data = secure_loads(session_cookie_data, cookie_key, compression_level=compression_level) if data: self.update(data) # else if we are supposed to use file based sessions elif not db: response.session_storage_type = 'file' if global_settings.db_sessions is True \ or masterapp in global_settings.db_sessions: return response.session_new = False client = request.client and request.client.replace(':', '.') if response.session_id: if regex_session_id.match(response.session_id): response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) else: response.session_id = None # do not try load the data from file is these was data in cookie if response.session_id and not session_cookie_data: # os.path.exists(response.session_filename): try: response.session_file = \ open(response.session_filename, 'rb+') try: portalocker.lock(response.session_file, portalocker.LOCK_EX) response.session_locked = True self.update(cPickle.load(response.session_file)) response.session_file.seek(0) oc = response.session_filename.split('/')[-1]\ .split('-')[0] if check_client and client != oc: raise Exception("cookie attack") except: response.session_id = None finally: pass #This causes admin login to break. Must find out why. #self._close(response) except: response.session_file = None if not response.session_id: uuid = web2py_uuid() response.session_id = '%s-%s' % (client, uuid) if separate: prefix = separate(response.session_id) response.session_id = '%s/%s' % \ (prefix, response.session_id) response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) response.session_new = True # else the session goes in db else: response.session_storage_type = 'db' if global_settings.db_sessions is not True: global_settings.db_sessions.add(masterapp) if response.session_file: self._close(response) if settings.global_settings.web2py_runtime_gae: # in principle this could work without GAE request.tickets_db = db if masterapp == request.application: table_migrate = migrate else: table_migrate = False tname = tablename + '_' + masterapp table = db.get(tname, None) Field = db.Field if table is None: db.define_table( tname, Field('locked', 'boolean', default=False), Field('client_ip', length=64), Field('created_datetime', 'datetime', default=request.now), Field('modified_datetime', 'datetime'), Field('unique_key', length=64), Field('session_data', 'blob'), migrate=table_migrate, ) table = db[tname] # to allow for lazy table try: # Get session data out of the database (record_id, unique_key) = response.session_id.split(':') if record_id == '0': raise Exception('record_id == 0') # Select from database if not session_cookie_data: rows = db(table.id == record_id).select() # Make sure the session data exists in the database if len(rows) == 0 or rows[0].unique_key != unique_key: raise Exception('No record') # rows[0].update_record(locked=True) # Unpickle the data session_data = cPickle.loads(rows[0].session_data) self.update(session_data) except Exception: record_id = None unique_key = web2py_uuid() session_data = {} response.session_id = '%s:%s' % (record_id, unique_key) response.session_db_table = table response.session_db_record_id = record_id response.session_db_unique_key = unique_key # keep tablename parameter for use in session renew response.session_table_name = tablename rcookies = response.cookies rcookies[response.session_id_name] = response.session_id rcookies[response.session_id_name]['path'] = '/' if cookie_expires: rcookies[response. session_id_name]['expires'] = cookie_expires.strftime(FMT) # if not cookie_key, but session_data_name in cookies # expire session_data_name from cookies if session_cookie_data: rcookies[response.session_data_name] = 'expired' rcookies[response.session_data_name]['path'] = '/' rcookies[response.session_data_name]['expires'] = PAST if self.flash: (response.flash, self.flash) = (self.flash, None)
def connect( self, request, response, db=None, tablename='web2py_session', masterapp=None, migrate=True, separate=None, check_client=False, cookie_key=None, ): """ separate can be separate=lambda(session_name): session_name[-2:] and it is used to determine a session prefix. separate can be True and it is set to session_name[-2:] """ if separate == True: separate = lambda session_name: session_name[-2:] self._unlock(response) if not masterapp: masterapp = request.application response.session_id_name = 'session_id_%s' % masterapp.lower() # Load session data from cookie cookies = request.cookies if cookie_key: response.session_cookie_key = cookie_key response.session_cookie_key2 = hashlib.md5(cookie_key).digest() cookie_name = masterapp.lower() + '_session_data' response.session_cookie_name = cookie_name if cookie_name in cookies: cookie_value = cookies[cookie_name].value cookie_parts = cookie_value.split(":") enc = cookie_parts[2] cipher = AES.new(cookie_key) decrypted = cipher.decrypt(base64.b64decode(enc)).rstrip('{') check = hmac.new(response.session_cookie_key2, enc).hexdigest() if cookie_parts[0] == check: session_data = cPickle.loads(decrypted) self.update(session_data) else: return if not db: if global_settings.db_sessions is True \ or masterapp in global_settings.db_sessions: return response.session_new = False client = request.client and request.client.replace(':', '.') if response.session_id_name in cookies: response.session_id = \ cookies[response.session_id_name].value if regex_session_id.match(response.session_id): response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) else: response.session_id = None if response.session_id: try: response.session_file = \ open(response.session_filename, 'rb+') try: portalocker.lock(response.session_file, portalocker.LOCK_EX) response.session_locked = True self.update(cPickle.load(response.session_file)) response.session_file.seek(0) oc = response.session_filename.split('/')[-1]\ .split('-')[0] if check_client and client != oc: raise Exception, "cookie attack" finally: pass #This causes admin login to break. Must find out why. #self._close(response) except: response.session_id = None if not response.session_id: uuid = web2py_uuid() response.session_id = '%s-%s' % (client, uuid) if separate: prefix = separate(response.session_id) response.session_id = '%s/%s' % \ (prefix,response.session_id) response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) response.session_new = True else: if global_settings.db_sessions is not True: global_settings.db_sessions.add(masterapp) response.session_db = True if response.session_file: self._close(response) if settings.global_settings.web2py_runtime_gae: # in principle this could work without GAE request.tickets_db = db if masterapp == request.application: table_migrate = migrate else: table_migrate = False tname = tablename + '_' + masterapp table = db.get(tname, None) Field = db.Field if table is None: db.define_table( tname, Field('locked', 'boolean', default=False), Field('client_ip', length=64), Field('created_datetime', 'datetime', default=request.now), Field('modified_datetime', 'datetime'), Field('unique_key', length=64), Field('session_data', 'blob'), migrate=table_migrate, ) table = db[tname] # to allow for lazy table try: # Get session data out of the database # Key comes from the cookie key = cookies[response.session_id_name].value (record_id, unique_key) = key.split(':') if record_id == '0': raise Exception, 'record_id == 0' # Select from database rows = db(table.id == record_id).select() # Make sure the session data exists in the database if len(rows) == 0 or rows[0].unique_key != unique_key: raise Exception, 'No record' # rows[0].update_record(locked=True) # Unpickle the data session_data = cPickle.loads(rows[0].session_data) self.update(session_data) except Exception: record_id = None unique_key = web2py_uuid() session_data = {} response._dbtable_and_field = \ (response.session_id_name, table, record_id, unique_key) response.session_id = '%s:%s' % (record_id, unique_key) rcookies = response.cookies rcookies[response.session_id_name] = response.session_id rcookies[response.session_id_name]['path'] = '/' self.__hash = hashlib.md5(str(self)).digest() if self.flash: (response.flash, self.flash) = (self.flash, None)
def renew(self, request=None, response=None, db=None, tablename='web2py_session', masterapp=None, clear_session=False): if request is None: request = current.request if response is None: response = current.response #check if session is separate separate = None if response.session and response.session_id[2:3] == "/": separate = lambda session_name: session_name[-2:] self._unlock(response) if not masterapp: masterapp = request.application # Load session data from cookie cookies = request.cookies # check if there is a session_id in cookies if response.session_id_name in cookies: response.session_id = \ cookies[response.session_id_name].value else: response.session_id = None # if the session goes in file if response.session_storage_type == 'file': if global_settings.db_sessions is True \ or masterapp in global_settings.db_sessions: return client = request.client and request.client.replace(':', '.') uuid = web2py_uuid() response.session_id = '%s-%s' % (client, uuid) if separate: prefix = separate(response.session_id) response.session_id = '%s/%s' % \ (prefix, response.session_id) response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) response.session_new = True # else the session goes in db elif response.session_storage_type == 'db': # verify that session_id exists if not response.session_id: return # verify if tablename was set or used in connect if response.session_table_name and tablename == 'web2py_session': tablename = response.session_table_name if global_settings.db_sessions is not True: global_settings.db_sessions.add(masterapp) if response.session_file: self._close(response) if settings.global_settings.web2py_runtime_gae: # in principle this could work without GAE request.tickets_db = db tname = tablename + '_' + masterapp if not db: raise Exception('No database parameter passed: "db=database"') table = db.get(tname, None) if table is None: raise Exception('No session to renew') # Get session data out of the database (record_id, unique_key) = response.session_id.split(':') if record_id == '0': raise Exception('record_id == 0') # Select from database row = db(table.id == record_id).select() row = row and row[0] or None # Make sure the session data exists in the database if not row or row.unique_key != unique_key: raise Exception('No record') unique_key = web2py_uuid() db(table.id == record_id).update(unique_key=unique_key) response.session_id = '%s:%s' % (record_id, unique_key) response.session_db_table = table response.session_db_record_id = record_id response.session_db_unique_key = unique_key rcookies = response.cookies if response.session_id_name: rcookies[response.session_id_name] = response.session_id rcookies[response.session_id_name]['path'] = '/' if clear_session: self.clear()
def connect( self, request, response, db=None, tablename='web2py_session', masterapp=None, migrate=True, ): self._unlock(response) if not masterapp: masterapp = request.application response.session_id_name = 'session_id_%s' % masterapp if not db: if response.session_id_name in request.cookies: response.session_id = \ request.cookies[response.session_id_name].value if regex_session_id.match(response.session_id): response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) else: response.session_id = None if response.session_id: try: response.session_file = \ open(response.session_filename, 'rb+') portalocker.lock(response.session_file, portalocker.LOCK_EX) self.update(cPickle.load(response.session_file)) response.session_file.seek(0) except: self._unlock(response) if response.session_file: # Only if open succeeded and later an exception was raised response.session_file.close() del response.session_file response.session_id = None if not response.session_id: response.session_id = '%s-%s'\ % (request.client.replace(':', '-').replace('.', '-'), web2py_uuid()) response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) response.session_new = True else: if settings.web2py_runtime_gae: # in principle this could work without GAE request.tickets_db = db if masterapp == request.application: table_migrate = migrate else: table_migrate = False tname = tablename + '_' + masterapp table = db.get(tname, None) if table is None: table = db.define_table( tname, db.Field('locked', 'boolean', default=False), db.Field('client_ip', length=64), db.Field('created_datetime', 'datetime', default=request.now), db.Field('modified_datetime', 'datetime'), db.Field('unique_key', length=64), db.Field('session_data', 'blob'), migrate=table_migrate, ) try: key = request.cookies[response.session_id_name].value (record_id, unique_key) = key.split(':') if record_id == '0': raise Exception, 'record_id == 0' rows = db(table.id == record_id).select() if len(rows) == 0 or rows[0].unique_key != unique_key: raise Exception, 'No record' # rows[0].update_record(locked=True) session_data = cPickle.loads(rows[0].session_data) self.update(session_data) except Exception: record_id = None unique_key = web2py_uuid() session_data = {} response._dbtable_and_field = \ (response.session_id_name, table, record_id, unique_key) response.session_id = '%s:%s' % (record_id, unique_key) response.cookies[response.session_id_name] = response.session_id response.cookies[response.session_id_name]['path'] = '/' if self.flash: (response.flash, self.flash) = (self.flash, None)
def connect( self, request, response, db=None, tablename='web2py_session', masterapp=None, migrate=True, separate = None, check_client=False, ): """ separate can be separate=lambda(session_name): session_name[-2:] and it is used to determine a session prefix. separate can be True and it is set to session_name[-2:] """ if separate == True: separate = lambda session_name: session_name[-2:] self._unlock(response) if not masterapp: masterapp = request.application response.session_id_name = 'session_id_%s' % masterapp.lower() if not db: if global_settings.db_sessions is True or masterapp in global_settings.db_sessions: return response.session_new = False client = request.client and request.client.replace(':', '.') if response.session_id_name in request.cookies: response.session_id = \ request.cookies[response.session_id_name].value if regex_session_id.match(response.session_id): response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) else: response.session_id = None if response.session_id: try: response.session_file = \ open(response.session_filename, 'rb+') try: portalocker.lock(response.session_file,portalocker.LOCK_EX) response.session_locked = True self.update(cPickle.load(response.session_file)) response.session_file.seek(0) oc = response.session_filename.split('/')[-1].split('-')[0] if check_client and client!=oc: raise Exception, "cookie attack" finally: pass #This causes admin login to break. Must find out why. #self._close(response) except: response.session_id = None if not response.session_id: uuid = web2py_uuid() response.session_id = '%s-%s' % (client, uuid) if separate: prefix = separate(response.session_id) response.session_id = '%s/%s' % (prefix,response.session_id) response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) response.session_new = True else: if global_settings.db_sessions is not True: global_settings.db_sessions.add(masterapp) response.session_db = True if response.session_file: self._close(response) if settings.global_settings.web2py_runtime_gae: # in principle this could work without GAE request.tickets_db = db if masterapp == request.application: table_migrate = migrate else: table_migrate = False tname = tablename + '_' + masterapp table = db.get(tname, None) if table is None: table = db.define_table( tname, db.Field('locked', 'boolean', default=False), db.Field('client_ip', length=64), db.Field('created_datetime', 'datetime', default=request.now), db.Field('modified_datetime', 'datetime'), db.Field('unique_key', length=64), db.Field('session_data', 'blob'), migrate=table_migrate, ) try: key = request.cookies[response.session_id_name].value (record_id, unique_key) = key.split(':') if record_id == '0': raise Exception, 'record_id == 0' rows = db(table.id == record_id).select() if len(rows) == 0 or rows[0].unique_key != unique_key: raise Exception, 'No record' # rows[0].update_record(locked=True) session_data = cPickle.loads(rows[0].session_data) self.update(session_data) except Exception: record_id = None unique_key = web2py_uuid() session_data = {} response._dbtable_and_field = \ (response.session_id_name, table, record_id, unique_key) response.session_id = '%s:%s' % (record_id, unique_key) response.cookies[response.session_id_name] = response.session_id response.cookies[response.session_id_name]['path'] = '/' self.__hash = hashlib.md5(str(self)).digest() if self.flash: (response.flash, self.flash) = (self.flash, None)
def connect( self, request=None, response=None, db=None, tablename='web2py_session', masterapp=None, migrate=True, separate=None, check_client=False, cookie_key=None, cookie_expires=None, compression_level=None ): """ separate can be separate=lambda(session_name): session_name[-2:] and it is used to determine a session prefix. separate can be True and it is set to session_name[-2:] """ request = request or current.request response = response or current.response masterapp = masterapp or request.application cookies = request.cookies self._unlock(response) response.session_masterapp = masterapp response.session_id_name = 'session_id_%s' % masterapp.lower() response.session_data_name = 'session_data_%s' % masterapp.lower() response.session_cookie_expires = cookie_expires response.session_client = str(request.client).replace(':', '.') response.session_cookie_key = cookie_key response.session_cookie_compression_level = compression_level # check if there is a session_id in cookies try: response.session_id = cookies[response.session_id_name].value except KeyError: response.session_id = None # if we are supposed to use cookie based session data if cookie_key: response.session_storage_type = 'cookie' elif db: response.session_storage_type = 'db' else: response.session_storage_type = 'file' # why do we do this? # because connect may be called twice, by web2py and in models. # the first time there is no db yet so it should do nothing if (global_settings.db_sessions is True or masterapp in global_settings.db_sessions): return if response.session_storage_type == 'cookie': # check if there is session data in cookies if response.session_data_name in cookies: session_cookie_data = cookies[response.session_data_name].value else: session_cookie_data = None if session_cookie_data: data = secure_loads(session_cookie_data, cookie_key, compression_level=compression_level) if data: self.update(data) response.session_id = True # else if we are supposed to use file based sessions elif response.session_storage_type == 'file': response.session_new = False response.session_file = None # check if the session_id points to a valid sesion filename if response.session_id: if not regex_session_id.match(response.session_id): response.session_id = None else: response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) try: response.session_file = \ open(response.session_filename, 'rb+') portalocker.lock(response.session_file, portalocker.LOCK_EX) response.session_locked = True self.update(cPickle.load(response.session_file)) response.session_file.seek(0) oc = response.session_filename.split('/')[-1].split('-')[0] if check_client and response.session_client != oc: raise Exception("cookie attack") except: response.session_id = None if not response.session_id: uuid = web2py_uuid() response.session_id = '%s-%s' % (response.session_client, uuid) separate = separate and (lambda session_name: session_name[-2:]) if separate: prefix = separate(response.session_id) response.session_id = '%s/%s' % (prefix, response.session_id) response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) response.session_new = True # else the session goes in db elif response.session_storage_type == 'db': if global_settings.db_sessions is not True: global_settings.db_sessions.add(masterapp) # if had a session on file alreday, close it (yes, can happen) if response.session_file: self._close(response) # if on GAE tickets go also in DB if settings.global_settings.web2py_runtime_gae: request.tickets_db = db table_migrate = (masterapp == request.application) tname = tablename + '_' + masterapp table = db.get(tname, None) Field = db.Field if table is None: db.define_table( tname, Field('locked', 'boolean', default=False), Field('client_ip', length=64), Field('created_datetime', 'datetime', default=request.now), Field('modified_datetime', 'datetime'), Field('unique_key', length=64), Field('session_data', 'blob'), migrate=table_migrate, ) table = db[tname] # to allow for lazy table response.session_db_table = table if response.session_id: # Get session data out of the database try: (record_id, unique_key) = response.session_id.split(':') record_id = long(record_id) except (TypeError,ValueError): record_id = None # Select from database if record_id: row = table(record_id) #,unique_key=unique_key) # Make sure the session data exists in the database if row: # rows[0].update_record(locked=True) # Unpickle the data session_data = cPickle.loads(row.session_data) self.update(session_data) else: record_id = None if record_id: response.session_id = '%s:%s' % (record_id, unique_key) response.session_db_unique_key = unique_key response.session_db_record_id = record_id else: response.session_id = None response.session_new = True if self.flash: (response.flash, self.flash) = (self.flash, None)
def connect(self, request=None, response=None, db=None, tablename='web2py_session', masterapp=None, migrate=True, separate=None, check_client=False, cookie_key=None, cookie_expires=None, compression_level=None): """ separate can be separate=lambda(session_name): session_name[-2:] and it is used to determine a session prefix. separate can be True and it is set to session_name[-2:] """ request = request or current.request response = response or current.response masterapp = masterapp or request.application cookies = request.cookies self._unlock(response) response.session_masterapp = masterapp response.session_id_name = 'session_id_%s' % masterapp.lower() response.session_data_name = 'session_data_%s' % masterapp.lower() response.session_cookie_expires = cookie_expires response.session_client = str(request.client).replace(':', '.') response.session_cookie_key = cookie_key response.session_cookie_compression_level = compression_level # check if there is a session_id in cookies try: response.session_id = cookies[response.session_id_name].value except KeyError: response.session_id = None # if we are supposed to use cookie based session data if cookie_key: response.session_storage_type = 'cookie' elif db: response.session_storage_type = 'db' else: response.session_storage_type = 'file' # why do we do this? # because connect may be called twice, by web2py and in models. # the first time there is no db yet so it should do nothing if (global_settings.db_sessions is True or masterapp in global_settings.db_sessions): return if response.session_storage_type == 'cookie': # check if there is session data in cookies if response.session_data_name in cookies: session_cookie_data = cookies[response.session_data_name].value else: session_cookie_data = None if session_cookie_data: data = secure_loads(session_cookie_data, cookie_key, compression_level=compression_level) if data: self.update(data) response.session_id = True # else if we are supposed to use file based sessions elif response.session_storage_type == 'file': response.session_new = False response.session_file = None # check if the session_id points to a valid sesion filename if response.session_id: if not regex_session_id.match(response.session_id): response.session_id = None else: response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) try: response.session_file = \ open(response.session_filename, 'rb+') portalocker.lock(response.session_file, portalocker.LOCK_EX) response.session_locked = True self.update(cPickle.load(response.session_file)) response.session_file.seek(0) oc = response.session_filename.split('/')[-1].split( '-')[0] if check_client and response.session_client != oc: raise Exception("cookie attack") except: response.session_id = None if not response.session_id: uuid = web2py_uuid() response.session_id = '%s-%s' % (response.session_client, uuid) separate = separate and ( lambda session_name: session_name[-2:]) if separate: prefix = separate(response.session_id) response.session_id = '%s/%s' % (prefix, response.session_id) response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) response.session_new = True # else the session goes in db elif response.session_storage_type == 'db': if global_settings.db_sessions is not True: global_settings.db_sessions.add(masterapp) # if had a session on file alreday, close it (yes, can happen) if response.session_file: self._close(response) # if on GAE tickets go also in DB if settings.global_settings.web2py_runtime_gae: request.tickets_db = db table_migrate = (masterapp == request.application) tname = tablename + '_' + masterapp table = db.get(tname, None) Field = db.Field if table is None: db.define_table( tname, Field('locked', 'boolean', default=False), Field('client_ip', length=64), Field('created_datetime', 'datetime', default=request.now), Field('modified_datetime', 'datetime'), Field('unique_key', length=64), Field('session_data', 'blob'), migrate=table_migrate, ) table = db[tname] # to allow for lazy table response.session_db_table = table if response.session_id: # Get session data out of the database try: (record_id, unique_key) = response.session_id.split(':') record_id = long(record_id) except (TypeError, ValueError): record_id = None # Select from database if record_id: row = table(record_id) #,unique_key=unique_key) # Make sure the session data exists in the database if row: # rows[0].update_record(locked=True) # Unpickle the data session_data = cPickle.loads(row.session_data) self.update(session_data) else: record_id = None if record_id: response.session_id = '%s:%s' % (record_id, unique_key) response.session_db_unique_key = unique_key response.session_db_record_id = record_id else: response.session_id = None response.session_new = True if self.flash: (response.flash, self.flash) = (self.flash, None) session_pickled = cPickle.dumps(self) response.session_hash = hashlib.md5(session_pickled).hexdigest()
def connect( self, request, response, db=None, tablename='web2py_session', masterapp=None, migrate=True, separate=None, check_client=False, ): """ separate can be separate=lambda(session_name): session_name[-2:] and it is used to determine a session prefix. separate can be True and it is set to session_name[-2:] """ if separate == True: separate = lambda session_name: session_name[-2:] self._unlock(response) if not masterapp: masterapp = request.application response.session_id_name = 'session_id_%s' % masterapp.lower() if not db: if global_settings.db_sessions is True or masterapp in global_settings.db_sessions: return response.session_new = False client = request.client.replace(':', '.') if response.session_id_name in request.cookies: response.session_id = \ request.cookies[response.session_id_name].value if regex_session_id.match(response.session_id): response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) else: response.session_id = None if response.session_id: try: response.session_file = \ open(response.session_filename, 'rb+') portalocker.lock(response.session_file, portalocker.LOCK_EX) response.session_locked = True self.update(cPickle.load(response.session_file)) response.session_file.seek(0) oc = response.session_filename.split('/')[-1].split('-')[0] if check_client and client != oc: raise Exception, "cookie attack" except: self._close(response) response.session_id = None if not response.session_id: uuid = web2py_uuid() response.session_id = '%s-%s' % (client, uuid) if separate: prefix = separate(response.session_id) response.session_id = '%s/%s' % (prefix, response.session_id) response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) response.session_new = True else: if global_settings.db_sessions is not True: global_settings.db_sessions.add(masterapp) response.session_db = True if response.session_file: self._close(response) if settings.global_settings.web2py_runtime_gae: # in principle this could work without GAE request.tickets_db = db if masterapp == request.application: table_migrate = migrate else: table_migrate = False tname = tablename + '_' + masterapp table = db.get(tname, None) if table is None: table = db.define_table( tname, db.Field('locked', 'boolean', default=False), db.Field('client_ip', length=64), db.Field('created_datetime', 'datetime', default=request.now), db.Field('modified_datetime', 'datetime'), db.Field('unique_key', length=64), db.Field('session_data', 'blob'), migrate=table_migrate, ) try: key = request.cookies[response.session_id_name].value (record_id, unique_key) = key.split(':') if record_id == '0': raise Exception, 'record_id == 0' rows = db(table.id == record_id).select() if len(rows) == 0 or rows[0].unique_key != unique_key: raise Exception, 'No record' # rows[0].update_record(locked=True) session_data = cPickle.loads(rows[0].session_data) self.update(session_data) except Exception: record_id = None unique_key = web2py_uuid() session_data = {} response._dbtable_and_field = \ (response.session_id_name, table, record_id, unique_key) response.session_id = '%s:%s' % (record_id, unique_key) response.cookies[response.session_id_name] = response.session_id response.cookies[response.session_id_name]['path'] = '/' self.__hash = hashlib.md5(str(self)).digest() if self.flash: (response.flash, self.flash) = (self.flash, None)
def connect( self, request, response, db=None, tablename='web2py_session', masterapp=None, migrate=True, ): self._unlock(response) if not masterapp: masterapp = request.application response.session_id_name = 'session_id_%s' % masterapp if not db: if response.session_id_name in request.cookies: response.session_id = \ request.cookies[response.session_id_name].value if regex_session_id.match(response.session_id): response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) else: response.session_id = None if response.session_id: try: response.session_file = \ open(response.session_filename, 'rb+') portalocker.lock(response.session_file, portalocker.LOCK_EX) self.update(cPickle.load(response.session_file)) response.session_file.seek(0) except: self._unlock(response) response.session_id = None if not response.session_id: response.session_id = '%s-%s'\ % (request.client.replace(':', '-').replace('.', '-'), uuid.uuid4()) response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) response.session_new = True else: if settings.web2py_runtime_gae: # in principle this could work without GAE request.tickets_db = db if masterapp == request.application: table_migrate = migrate else: table_migrate = False tname = tablename + '_' + masterapp table = db.get(tname, None) if table is None: table = db.define_table( tname, db.Field('locked', 'boolean', default=False), db.Field('client_ip', length=64), db.Field('created_datetime', 'datetime', default=request.now), db.Field('modified_datetime', 'datetime'), db.Field('unique_key', length=64), db.Field('session_data', 'blob'), migrate=table_migrate, ) try: key = request.cookies[response.session_id_name].value (record_id, unique_key) = key.split(':') if record_id == '0': raise Exception, 'record_id == 0' rows = db(table.id == record_id).select() if len(rows) == 0 or rows[0].unique_key != unique_key: raise Exception, 'No record' # rows[0].update_record(locked=True) session_data = cPickle.loads(rows[0].session_data) self.update(session_data) except Exception, e: (record_id, unique_key, session_data) = \ (None, str(uuid.uuid4()), {}) response._dbtable_and_field = \ (response.session_id_name, table, record_id, unique_key) response.session_id = '%s:%s' % (record_id, unique_key)
def renew( self, request=None, response=None, db=None, tablename='web2py_session', masterapp=None, clear_session=False ): if request is None: request = current.request if response is None: response = current.response #check if session is separate separate = None if response.session and response.session_id[2:3] == "/": separate = lambda session_name: session_name[-2:] self._unlock(response) if not masterapp: masterapp = request.application # Load session data from cookie cookies = request.cookies # check if there is a session_id in cookies if response.session_id_name in cookies: response.session_id = \ cookies[response.session_id_name].value else: response.session_id = None # if the session goes in file if response.session_storage_type == 'file': if global_settings.db_sessions is True \ or masterapp in global_settings.db_sessions: return client = request.client and request.client.replace(':', '.') uuid = web2py_uuid() response.session_id = '%s-%s' % (client, uuid) if separate: prefix = separate(response.session_id) response.session_id = '%s/%s' % \ (prefix, response.session_id) response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) response.session_new = True # else the session goes in db elif response.session_storage_type == 'db': # verify that session_id exists if not response.session_id: return # verify if tablename was set or used in connect if response.session_table_name and tablename == 'web2py_session': tablename = response.session_table_name if global_settings.db_sessions is not True: global_settings.db_sessions.add(masterapp) if response.session_file: self._close(response) if settings.global_settings.web2py_runtime_gae: # in principle this could work without GAE request.tickets_db = db tname = tablename + '_' + masterapp if not db: raise Exception('No database parameter passed: "db=database"') table = db.get(tname, None) if table is None: raise Exception('No session to renew') # Get session data out of the database (record_id, unique_key) = response.session_id.split(':') if record_id == '0': raise Exception('record_id == 0') # Select from database row = record_id and db(table.id == record_id).select() row = row and row[0] or None # Make sure the session data exists in the database if not row or row.unique_key != unique_key: raise Exception('No record') unique_key = web2py_uuid() db(table.id == record_id).update(unique_key=unique_key) response.session_id = '%s:%s' % (record_id, unique_key) response.session_db_table = table response.session_db_record_id = record_id response.session_db_unique_key = unique_key rcookies = response.cookies if response.session_id_name: rcookies[response.session_id_name] = response.session_id rcookies[response.session_id_name]['path'] = '/' if clear_session: self.clear()
def connect( self, request=None, response=None, db=None, tablename='web2py_session', masterapp=None, migrate=True, separate=None, check_client=False, cookie_key=None, cookie_expires=None, compression_level=None ): """ separate can be separate=lambda(session_name): session_name[-2:] and it is used to determine a session prefix. separate can be True and it is set to session_name[-2:] """ if request is None: request = current.request if response is None: response = current.response if separate == True: separate = lambda session_name: session_name[-2:] self._unlock(response) if not masterapp: masterapp = request.application response.session_id_name = 'session_id_%s' % masterapp.lower() response.session_data_name = 'session_data_%s' % masterapp.lower() response.session_cookie_expires = cookie_expires # Load session data from cookie cookies = request.cookies # check if there is a session_id in cookies if response.session_id_name in cookies: response.session_id = \ cookies[response.session_id_name].value else: response.session_id = None # check if there is session data in cookies if response.session_data_name in cookies: session_cookie_data = cookies[response.session_data_name].value else: session_cookie_data = None # if we are supposed to use cookie based session data if cookie_key: response.session_storage_type = 'cookie' response.session_cookie_key = cookie_key response.session_cookie_compression_level = compression_level if session_cookie_data: data = secure_loads(session_cookie_data, cookie_key, compression_level=compression_level) if data: self.update(data) # else if we are supposed to use file based sessions elif not db: response.session_storage_type = 'file' if global_settings.db_sessions is True \ or masterapp in global_settings.db_sessions: return response.session_new = False client = request.client and request.client.replace(':', '.') if response.session_id: if regex_session_id.match(response.session_id): response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) else: response.session_id = None # do not try load the data from file is these was data in cookie if response.session_id and not session_cookie_data: try: response.session_file = \ open(response.session_filename, 'rb+') try: portalocker.lock(response.session_file, portalocker.LOCK_EX) response.session_locked = True self.update(cPickle.load(response.session_file)) response.session_file.seek(0) oc = response.session_filename.split('/')[-1]\ .split('-')[0] if check_client and client != oc: raise Exception("cookie attack") finally: pass #This causes admin login to break. Must find out why. #self._close(response) except: response.session_id = None if not response.session_id: uuid = web2py_uuid() response.session_id = '%s-%s' % (client, uuid) if separate: prefix = separate(response.session_id) response.session_id = '%s/%s' % \ (prefix, response.session_id) response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) response.session_new = True # else the session goes in db else: response.session_storage_type = 'db' if global_settings.db_sessions is not True: global_settings.db_sessions.add(masterapp) if response.session_file: self._close(response) if settings.global_settings.web2py_runtime_gae: # in principle this could work without GAE request.tickets_db = db if masterapp == request.application: table_migrate = migrate else: table_migrate = False tname = tablename + '_' + masterapp table = db.get(tname, None) Field = db.Field if table is None: db.define_table( tname, Field('locked', 'boolean', default=False), Field('client_ip', length=64), Field('created_datetime', 'datetime', default=request.now), Field('modified_datetime', 'datetime'), Field('unique_key', length=64), Field('session_data', 'blob'), migrate=table_migrate, ) table = db[tname] # to allow for lazy table try: # Get session data out of the database (record_id, unique_key) = response.session_id.split(':') if record_id == '0': raise Exception('record_id == 0') # Select from database if not session_cookie_data: rows = db(table.id == record_id).select() # Make sure the session data exists in the database if len(rows) == 0 or rows[0].unique_key != unique_key: raise Exception('No record') # rows[0].update_record(locked=True) # Unpickle the data session_data = cPickle.loads(rows[0].session_data) self.update(session_data) except Exception: record_id = None unique_key = web2py_uuid() session_data = {} response.session_id = '%s:%s' % (record_id, unique_key) response.session_db_table = table response.session_db_record_id = record_id response.session_db_unique_key = unique_key rcookies = response.cookies rcookies[response.session_id_name] = response.session_id rcookies[response.session_id_name]['path'] = '/' if cookie_expires: rcookies[response.session_id_name][ 'expires'] = cookie_expires.strftime(FMT) # if not cookie_key, but session_data_name in cookies # expire session_data_name from cookies if session_cookie_data: rcookies[response.session_data_name] = 'expired' rcookies[response.session_data_name]['path'] = '/' rcookies[response.session_data_name]['expires'] = PAST if self.flash: (response.flash, self.flash) = (self.flash, None)
def connect( self, request, response, db=None, tablename='web2py_session', masterapp=None, migrate=True, ): self._unlock(response) if not masterapp: masterapp = request.application response.session_id_name = 'session_id_%s' % masterapp if not db: if request.cookies.has_key(response.session_id_name): response.session_id = \ request.cookies[response.session_id_name].value if regex_session_id.match(response.session_id): response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) else: response.session_id = None if response.session_id: try: response.session_file = \ open(response.session_filename, 'rb+') portalocker.lock(response.session_file, portalocker.LOCK_EX) self.update(cPickle.load(response.session_file)) response.session_file.seek(0) except: self._unlock(response) response.session_id = None if not response.session_id: response.session_id = '%s-%s'\ % (request.client.replace(':', '-').replace('.', '-'), uuid.uuid4()) response.session_filename = \ os.path.join(up(request.folder), masterapp, 'sessions', response.session_id) response.session_new = True else: if masterapp == request.application: table_migrate = migrate else: table_migrate = False tname = tablename + '_' + masterapp table = db.get(tname, None) if table is None: table = db.define_table( tname, db.Field('locked', 'boolean', default=False), db.Field('client_ip', length=64), db.Field('created_datetime', 'datetime', default=request.now), db.Field('modified_datetime', 'datetime'), db.Field('unique_key', length=64), db.Field('session_data', 'blob'), migrate=table_migrate, ) try: key = request.cookies[response.session_id_name].value (record_id, unique_key) = key.split(':') if record_id == '0': raise Exception rows = db(table.id == record_id).select() if len(rows) == 0 or rows[0].unique_key != unique_key: raise Exception, 'No record' # rows[0].update_record(locked=True) session_data = cPickle.loads(rows[0].session_data) self.update(session_data) except Exception, e: (record_id, unique_key, session_data) = (None, str(uuid.uuid4()), {}) finally: