summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/api.rst1
-rw-r--r--docs/api/interfaces.rst4
-rw-r--r--docs/api/request.rst8
-rw-r--r--docs/api/session.rst9
-rw-r--r--docs/glossary.rst11
-rw-r--r--docs/index.rst1
-rw-r--r--docs/narr/security.rst2
-rw-r--r--docs/narr/sessions.rst152
-rw-r--r--docs/narr/webob.rst12
-rw-r--r--pyramid/interfaces.py12
-rw-r--r--pyramid/request.py2
-rw-r--r--pyramid/session.py46
12 files changed, 246 insertions, 14 deletions
diff --git a/docs/api.rst b/docs/api.rst
index 8d93ff450..8e7c0c283 100644
--- a/docs/api.rst
+++ b/docs/api.rst
@@ -25,6 +25,7 @@ documentation is organized alphabetically by module name.
api/router
api/scripting
api/security
+ api/session
api/settings
api/testing
api/threadlocal
diff --git a/docs/api/interfaces.rst b/docs/api/interfaces.rst
index 7193fd11b..2bf55474e 100644
--- a/docs/api/interfaces.rst
+++ b/docs/api/interfaces.rst
@@ -25,3 +25,7 @@ Other Interfaces
.. autointerface:: IRoutePregenerator
+ .. autointerface:: ISession
+
+ .. autointerface:: ISessionFactory
+
diff --git a/docs/api/request.rst b/docs/api/request.rst
index e53028b0f..9e851ba8d 100644
--- a/docs/api/request.rst
+++ b/docs/api/request.rst
@@ -85,3 +85,11 @@
of ``request.exception`` will be ``None`` within response and
finished callbacks.
+ .. attribute:: session
+
+ If a :term:`session factory` has been configured, this attribute
+ will represent the current user's :term:`session` object. If a
+ session factory *has not* been configured, requesting the
+ ``request.session`` attribute will cause a
+ :class:`pyramid.exceptions.ConfigurationError` to be raised.
+
diff --git a/docs/api/session.rst b/docs/api/session.rst
new file mode 100644
index 000000000..daed9fc33
--- /dev/null
+++ b/docs/api/session.rst
@@ -0,0 +1,9 @@
+.. _session_module:
+
+:mod:`pyramid.session`
+---------------------------
+
+.. automodule:: pyramid.session
+
+ .. autofunction:: InsecureCookieSessionFactoryConfig
+
diff --git a/docs/glossary.rst b/docs/glossary.rst
index 2e2b11aaa..93d86b664 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -803,3 +803,14 @@ Glossary
``route_url``. See
:class:`repoze.bfg.interfaces.IRoutePregenerator` for more
information.
+
+ session
+ A namespace that is valid for some period of continual activity
+ that can be used to represent a user's interaction with a web
+ application.
+
+ session factory
+ A callable, which, when called with a single argument named
+ ``request`` (a :term:`request` object), returns a
+ :term:`session` object.
+
diff --git a/docs/index.rst b/docs/index.rst
index 3b62b5fac..c774c11d1 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -40,6 +40,7 @@ Narrative documentation in chapter form explaining how to use
narr/views
narr/static
narr/webob
+ narr/sessions
narr/templates
narr/models
narr/security
diff --git a/docs/narr/security.rst b/docs/narr/security.rst
index 109009842..5782837aa 100644
--- a/docs/narr/security.rst
+++ b/docs/narr/security.rst
@@ -241,7 +241,7 @@ application:
When a default permission is registered:
-- if a view configuration names an explicit ``permission`, the default
+- if a view configuration names an explicit ``permission``, the default
permission is ignored for that view registration, and the
view-configuration-named permission is used.
diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst
new file mode 100644
index 000000000..e460e2d74
--- /dev/null
+++ b/docs/narr/sessions.rst
@@ -0,0 +1,152 @@
+.. index::
+ single: session
+
+.. _sessions_chapter:
+
+Session Objects
+===============
+
+A :term:`session` is a namespace which is valid for some period of
+continual activity that can be used to represent a user's interaction
+with a web application.
+
+Using The Default Session Factory
+---------------------------------
+
+In order to use sessions, you must set up a :term:`session factory`
+during your :mod:`pyramid` configuration.
+
+A very basic, insecure sample session factory implementation is
+provided in the :mod:`pyramid` core. It uses a cookie to store
+session information. This implementation has the following
+limitation:
+
+- The session information in the cookies used by this implementation
+ is *not* encrypted, so it can be viewed by anyone with access to the
+ cookie storage of the user's browser or anyone with access to the
+ network along which the cookie travels.
+
+- The maximum number of bytes that are storable in a serialized
+ representation of the session is fewer than 4000. Only very small
+ data sets can be kept in this
+
+It is, however, digitally signed, and thus its data cannot easily be
+tampered with.
+
+You can configure this session factory in your :mod:`pyramid`
+application by using the ``session_factory`` argument to the
+:class:`pyramid.configuration.Configurator` class:
+
+.. code-block:: python
+ :linenos:
+
+ from pyramid.session import InsecureCookieSessionFactoryConfig
+ my_session_factory = InsecureCookieSessionFactoryConfig('itsaseekreet')
+
+ from pyramid.configuration import Configurator
+ config = Configurator(session_factory = my_session_factory)
+
+.. warning::
+
+ Note the very long, very explicit name for
+ ``InsecureCookieSessionFactoryConfig``. It's trying to tell you
+ that this implementation is, by default, *insecure*. You should
+ not use it when you keep sensitive information in the session
+ object, as the information can be easily read by both users of your
+ application and third parties who have access to your users'
+ network traffic. Use a different session factory implementation
+ (preferably one which keeps session data on the server) for
+ anything but the most basic of applications where "session security
+ doesn't matter".
+
+Using a Session Object
+----------------------
+
+Once a session factory has been configured for your application, you
+can access session objects provided by the session factory by asking
+for the ``session`` attribute of any :term:`request` object. For
+example:
+
+.. code-block:: python
+ :linenos:
+
+ from webob import Response
+
+ def myview(request):
+ session = request.session
+ if 'abc' in session:
+ session['fred'] = 'yes'
+ session['abc'] = '123'
+ if 'fred' in session:
+ return Response('Fred was in the session')
+ else:
+ return Response('Fred was not in the session')
+
+You can use a session much like a Python dictionary. It supports all
+methods of a Python dictionary, and it has three extra attributes, and
+two extra methods.
+
+Extra attributes:
+
+``modified``
+ An integer timestamp indicating the last time the session was modified.
+
+``created``
+ An integer timestamp indicating the time that this session was created.
+
+``new``
+ A boolean. If ``new`` is True, this session is new. Otherwise, it has
+ been constituted from data that was already serialized.
+
+Extra methods:
+
+``changed()``
+ Call this when you mutate a mutable value in the session namespace.
+
+``invalidate()``
+ Call this when you want to invalidate the session (dump all data,
+ and -- perhaps -- set a clearing cookie).
+
+The formal definition of the methods and attributes supported by the
+session object are in the :class:`pyramid.interfaces.ISession`
+documentation.
+
+Some gotchas:
+
+- Keys and values of session data must be *pickleable*. This means,
+ typically, that they must be instances of basic types of objects,
+ such as strings, lists, dictionaries, tuples, integers, etc. If you
+ place an object in a session data key or value that is not
+ pickleable, an error will be raised when the session is serialized.
+
+- If you place a mutable value (for example, a list or a dictionary)
+ in a session object, and you subsequently mutate that value, you
+ must call the ``changed()`` method of the session object. This is
+ because, although the session object can detect when you call its
+ data-modifying methods such as ``__setitem__``, ``pop`` and other
+ (and thus the session knows it needs to reserialize the session
+ data), when you change a mutable object stored in the session
+ itself, the session has no way to know that you changed that value.
+ When in doubt, call ``changed()`` after you've changed sessioning
+ data.
+
+Using Alternate Session Factories
+---------------------------------
+
+At the time of this writing, alternate session factories don't yet
+exist. It is our intent that we will soon provide at least one other
+session factory which will be easily installable: one that uses the
+`Beaker <http://beaker.groovie.org/>`_ library as a backend.
+
+Creating Your Own Session Factory
+---------------------------------
+
+If none of the default or otherwise available sessioning
+implementations for :mod:`pyramid` suit you, you may create your own
+session object by implementing a :term:`session factory`. Your
+session factory should return a :term:`session`. The interfaces for
+both types are available in
+:class:`pyramid.interfaces.ISessionFactory` and
+:class:`pyramid.interfaces.ISession`. You might use the cookie
+implementation in the :mod:`pyramid.session` module as inspiration.
+
diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst
index b3bec882e..15f8da9cf 100644
--- a/docs/narr/webob.rst
+++ b/docs/narr/webob.rst
@@ -109,12 +109,12 @@ instance, ``req.if_modified_since`` returns a `datetime
Special Attributes Added to the Request by :mod:`pyramid`
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-In addition to the standard :term:`WebOb` attributes,
-:mod:`pyramid` adds special attributes to every request:
-``context``, ``registry``, ``root``, ``subpath``, ``traversed``,
-``view_name``, ``virtual_root`` , and ``virtual_root_path``. These
-attributes are documented further within the
-:class:`pyramid.request.Request` API documentation.
+In addition to the standard :term:`WebOb` attributes, :mod:`pyramid`
+adds special attributes to every request: ``context``, ``registry``,
+``root``, ``subpath``, ``traversed``, ``view_name``, ``virtual_root``
+, ``virtual_root_path``, and ``session``. These attributes are
+documented further within the :class:`pyramid.request.Request` API
+documentation.
.. index::
single: request URLs
diff --git a/pyramid/interfaces.py b/pyramid/interfaces.py
index 204d713b4..e1d7491b5 100644
--- a/pyramid/interfaces.py
+++ b/pyramid/interfaces.py
@@ -424,7 +424,7 @@ class ISession(Interface):
def __getitem__(key):
"""Get a value for a key
- A KeyError is raised if there is no value for the key.
+ A ``KeyError`` is raised if there is no value for the key.
"""
def get(key, default=None):
@@ -436,7 +436,7 @@ class ISession(Interface):
def __delitem__(key):
"""Delete a value from the mapping using the key.
- A KeyError is raised if there is no value for the key.
+ A ``KeyError`` is raised if there is no value for the key.
"""
def __setitem__(key, value):
@@ -470,17 +470,17 @@ class ISession(Interface):
" Update D from E: for k in E.keys(): D[k] = E[k]"
def setdefault(key, default=None):
- "D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D"
+ " D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D "
def pop(k, *args):
"""remove specified key and return the corresponding value
- *args may contain a single default value, or may not be supplied.
+ ``*args`` may contain a single default value, or may not be supplied.
If key is not found, default is returned if given, otherwise
- KeyError is raised"""
+ ``KeyError`` is raised"""
def popitem():
"""remove and return some (key, value) pair as a
- 2-tuple; but raise KeyError if mapping is empty"""
+ 2-tuple; but raise ``KeyError`` if mapping is empty"""
def __len__():
"""Return the number of items in the session.
diff --git a/pyramid/request.py b/pyramid/request.py
index b3e398b6d..7ffdb7495 100644
--- a/pyramid/request.py
+++ b/pyramid/request.py
@@ -151,7 +151,7 @@ class Request(WebobRequest):
if factory is None:
raise ConfigurationError(
'No session factory registered '
- '(use ``config.add_session_factory``)')
+ '(see the Session Objects chapter of the documentation)')
return factory(self)
# override default WebOb "environ['adhoc_attr']" mutation behavior
diff --git a/pyramid/session.py b/pyramid/session.py
index 88eb8720b..50f071398 100644
--- a/pyramid/session.py
+++ b/pyramid/session.py
@@ -49,6 +49,52 @@ def InsecureCookieSessionFactoryConfig(
cookie_httponly=False,
cookie_on_exception=False,
):
+ """
+ Configure a :term:`session factory` which will provide insecure
+ (but signed) cookie-based sessions. The return value of this
+ function is a :term:`session factory`, which may be provided as
+ the ``session_factory`` argument of a
+ :class:`pyramid.configuration.Configurator` constructor, or used
+ as the ``session_factory`` argument of the
+ :meth:`pyramid.configuration.Configurator.set_session_factory`
+ method.
+
+ The session factory returned by this function will create sessions
+ which are limited to storing fewer than 4000 bytes of data (as the
+ payload must fit into a single cookie).
+
+ Parameters:
+
+ ``secret``
+ A string which is used to sign the cookie.
+
+ ``timeout``
+ A number of seconds of inactivity before a session times out.
+
+ ``cookie_name``
+ The name of the cookie used for sessioning. Default: ``session``.
+
+ ``cookie_max_age``
+ The maximum age of the cookie used for sessioning (in seconds).
+ Default: ``None`` (browser scope).
+
+ ``cookie_path``
+ The path used for the session cookie. Default: ``/``.
+
+ ``cookie_domain``
+ The domain used for the session cookie. Default: ``None`` (no domain).
+
+ ``cookie_secure``
+ The 'secure' flag of the session cookie. Default: ``False``.
+
+ ``cookie_httponly``
+ The 'httpOnly' flag of the session cookie. Default: ``False``.
+
+ ``cookie_on_exception``
+ If ``True``, set a session cookie even if an exception occurs
+ while rendering a view. Default: ``False``.
+
+ """
class InsecureCookieSessionFactory(dict):
""" Dictionary-like session object """