Example #1
0
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('\\', '/')
Example #2
0
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('\\', '/')
Example #3
0
    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
Example #4
0
    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)
Example #6
0
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)
Example #7
0
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)
Example #9
0
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)
Example #10
0
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)
Example #11
0
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)
Example #12
0
    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)
Example #13
0
    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)
Example #14
0
    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)
Example #15
0
    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)
Example #16
0
    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)
Example #17
0
    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)
Example #18
0
    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()
Example #19
0
    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)
Example #20
0
    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)
Example #21
0
    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)
Example #22
0
    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()
Example #23
0
    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)
Example #24
0
    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)
Example #25
0
    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()
Example #26
0
    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)
Example #27
0
    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: