doc/book/en/devrepo/repo/sessions.rst
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 15 Sep 2011 18:39:55 +0200
changeset 7797 a71618a75b53
parent 7751 50f89f05ae0a
child 8760 17994bf95d6a
permissions -rw-r--r--
backport stable
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
     1
.. -*- coding: utf-8 -*-
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
     2
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
     3
Sessions
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
     4
========
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
     5
6311
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
     6
Sessions are object carrying the `.execute` method to query the data
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
     7
sources.
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
     8
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
     9
Kinds of sessions
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    10
-----------------
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    11
6298
f4347f796908 [doc/book] fix session types
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5394
diff changeset
    12
There are two kinds of sessions.
2112
df86450ca65d [doc] a note on sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1714
diff changeset
    13
6311
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    14
* `normal sessions` are the most common: they are related to users and
2112
df86450ca65d [doc] a note on sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1714
diff changeset
    15
  carry security checks coming with user credentials
df86450ca65d [doc] a note on sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1714
diff changeset
    16
2539
0f26a76b0348 [doc] some more rewriting
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2112
diff changeset
    17
* `internal sessions` have all the powers; they are also used in only a
2112
df86450ca65d [doc] a note on sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1714
diff changeset
    18
  few situations where you don't already have an adequate session at
df86450ca65d [doc] a note on sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1714
diff changeset
    19
  hand, like: user authentication, data synchronisation in
df86450ca65d [doc] a note on sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1714
diff changeset
    20
  multi-source contexts
df86450ca65d [doc] a note on sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1714
diff changeset
    21
2539
0f26a76b0348 [doc] some more rewriting
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2112
diff changeset
    22
.. note::
0f26a76b0348 [doc] some more rewriting
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2112
diff changeset
    23
  Do not confuse the session type with their connection mode, for
6311
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    24
  instance : `in memory` or `pyro`.
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    25
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    26
Normal sessions are typically named `_cw` in most appobjects or
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    27
sometimes just `session`.
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    28
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    29
Internal sessions are available from the `Repository` object and are
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    30
to be used like this:
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    31
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    32
.. sourcecode:: python
6313
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
    33
6311
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    34
   session = self.repo.internal_session()
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    35
   try:
6320
f2e925ae7122 [doc/book] make it colorful
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6319
diff changeset
    36
       do_stuff_with(session)
6311
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    37
   finally:
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    38
       session.close()
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    39
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    40
.. warning::
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    41
  Do not forget to close such a session after use for a session leak
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    42
  will quickly lead to an application crash.
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    43
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    44
Authentication and management of sessions
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    45
-----------------------------------------
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    46
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    47
The authentication process is a ballet involving a few dancers:
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    48
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    49
* through its `connect` method the top-level application object (the
6313
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
    50
  `CubicWebPublisher`) will open a session whenever a web request
6311
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    51
  comes in; it asks the `session manager` to open a session (giving
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    52
  the web request object as context) using `open_session`
2112
df86450ca65d [doc] a note on sessions
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1714
diff changeset
    53
6311
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    54
  * the session manager asks its authentication manager (which is a
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    55
    `component`) to authenticate the request (using `authenticate`)
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    56
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    57
    * the authentication manager asks, in order, to its authentication
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    58
      information retrievers, a login and an opaque object containing
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    59
      other credentials elements (calling `authentication_information`),
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    60
      giving the request object each time
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    61
7751
50f89f05ae0a [doc/book] fix ref to trustedauth cube
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6320
diff changeset
    62
      * the default retriever (oddly named `LoginPasswordRetreiver`)
50f89f05ae0a [doc/book] fix ref to trustedauth cube
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6320
diff changeset
    63
        will in turn defer login and password fetching to the request
50f89f05ae0a [doc/book] fix ref to trustedauth cube
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6320
diff changeset
    64
        object (which, depending on the authentication mode (`cookie`
50f89f05ae0a [doc/book] fix ref to trustedauth cube
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6320
diff changeset
    65
        or `http`), will do the appropriate things and return a login
50f89f05ae0a [doc/book] fix ref to trustedauth cube
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6320
diff changeset
    66
        and a password)
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    67
6311
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    68
    * the authentication manager, on success, asks the `Repository`
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    69
      object to connect with the found credentials (using `connect`)
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    70
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    71
      * the repository object asks authentication to all of its
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    72
        sources which support the `CWUser` entity with the given
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    73
        credentials; when successful it can build the cwuser entity,
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    74
        from which a regular `Session` object is made; it returns the
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    75
        session id
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    76
7751
50f89f05ae0a [doc/book] fix ref to trustedauth cube
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6320
diff changeset
    77
        * the source in turn will delegate work to an authentifier
50f89f05ae0a [doc/book] fix ref to trustedauth cube
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6320
diff changeset
    78
          class that defines the ultimate `authenticate` method (for
50f89f05ae0a [doc/book] fix ref to trustedauth cube
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6320
diff changeset
    79
          instance the native source will query the database against
50f89f05ae0a [doc/book] fix ref to trustedauth cube
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6320
diff changeset
    80
          the provided credentials)
6313
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
    81
6311
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    82
    * the authentication manager, on success, will call back _all_
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    83
      retrievers with `authenticated` and return its authentication
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    84
      data (on failure, it will try the anonymous login or, if the
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    85
      configuration forbids it, raise an `AuthenticationError`)
afd6a9e45489 [doc/book] tell a more complete story on sessions and the authentication process
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6298
diff changeset
    86
6313
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
    87
Writing authentication plugins
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
    88
------------------------------
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
    89
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
    90
Sometimes CubicWeb's out-of-the-box authentication schemes (cookie and
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
    91
http) are not sufficient. Nowadays there is a plethore of such schemes
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
    92
and the framework cannot provide them all, but as the sequence above
6319
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
    93
shows, it is extensible.
6313
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
    94
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
    95
Two levels have to be considered when writing an authentication
6319
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
    96
plugin: the web client and the repository.
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
    97
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
    98
We invented a scenario where it makes sense to have a new plugin in
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
    99
each side: some middleware will do pre-authentication and under the
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   100
right circumstances add a new HTTP `x-foo-user` header to the query
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   101
before it reaches the CubicWeb instance. For a concrete example of
7751
50f89f05ae0a [doc/book] fix ref to trustedauth cube
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6320
diff changeset
   102
this, see the `trustedauth`_ cube.
6319
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   103
7751
50f89f05ae0a [doc/book] fix ref to trustedauth cube
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6320
diff changeset
   104
.. _`trustedauth`: http://www.cubicweb.org/project/cubicweb-trustedauth
6319
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   105
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   106
Repository authentication plugins
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   107
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6313
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   108
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   109
On the repository side, it is possible to register a source
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   110
authentifier using the following kind of code:
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   111
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   112
.. sourcecode:: python
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   113
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   114
 from cubicweb.server.sources import native
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   115
6319
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   116
 class FooAuthentifier(native.LoginPasswordAuthentifier):
6313
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   117
     """ a source authentifier plugin
6319
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   118
     if 'foo' in authentication information, no need to check
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   119
     password
6313
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   120
     """
6319
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   121
     auth_rql = 'Any X WHERE X is CWUser, X login %(login)s'
6313
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   122
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   123
     def authenticate(self, session, login, **kwargs):
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   124
         """return CWUser eid for the given login
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   125
         if this account is defined in this source,
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   126
         else raise `AuthenticationError`
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   127
         """
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   128
         session.debug('authentication by %s', self.__class__.__name__)
6319
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   129
         if 'foo' not in kwargs:
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   130
             return super(FooAuthentifier, self).authenticate(session, login, **kwargs)
6313
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   131
         try:
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   132
             rset = session.execute(self.auth_rql, {'login': login})
6319
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   133
             return rset[0][0]
6313
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   134
         except Exception, exc:
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   135
             session.debug('authentication failure (%s)', exc)
6319
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   136
         raise AuthenticationError('foo user is unknown to us')
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   137
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   138
Since repository authentifiers are not appobjects, we have to register
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   139
them through a `server_startup` hook.
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   140
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   141
.. sourcecode:: python
6313
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   142
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   143
 class ServerStartupHook(hook.Hook):
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   144
     """ register the foo authenticator """
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   145
     __regid__ = 'fooauthenticatorregisterer'
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   146
     events = ('server_startup',)
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   147
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   148
     def __call__(self):
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   149
         self.debug('registering foo authentifier')
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   150
         self.repo.system_source.add_authentifier(FooAuthentifier())
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   151
6319
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   152
Web authentication plugins
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   153
~~~~~~~~~~~~~~~~~~~~~~~~~~
6313
b3fd91524132 [doc/book] begin an howto write auth plugins chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6311
diff changeset
   154
6319
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   155
.. sourcecode:: python
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   156
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   157
 class XFooUserRetriever(authentication.LoginPasswordRetreiver):
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   158
     """ authenticate by the x-foo-user http header
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   159
     or just do normal login/password authentication
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   160
     """
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   161
     __regid__ = 'x-foo-user'
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   162
     order = 0
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   163
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   164
     def authentication_information(self, req):
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   165
         """retrieve authentication information from the given request, raise
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   166
         NoAuthInfo if expected information is not found
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   167
         """
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   168
         self.debug('web authenticator building auth info')
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   169
         try:
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   170
            login = req.get_header('x-foo-user')
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   171
            if login:
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   172
                return login, {'foo': True}
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   173
            else:
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   174
                return super(XFooUserRetriever, self).authentication_information(self, req)
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   175
         except Exception, exc:
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   176
            self.debug('web authenticator failed (%s)', exc)
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   177
         raise authentication.NoAuthInfo()
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   178
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   179
     def authenticated(self, retriever, req, cnx, login, authinfo):
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   180
         """callback when return authentication information have opened a
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   181
         repository connection successfully. Take care req has no session
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   182
         attached yet, hence req.execute isn't available.
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   183
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   184
         Here we set a flag on the request to indicate that the user is
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   185
         foo-authenticated. Can be used by a selector
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   186
         """
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   187
         self.debug('web authenticator running post authentication callback')
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   188
         cnx.foo_user = authinfo.get('foo')
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   189
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   190
In the `authenticated` method we add (in an admitedly slightly hackish
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   191
way) an attribute to the connection object. This, in turn, can be used
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   192
to build a selector dispatching on the fact that the user was
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   193
preauthenticated or not.
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   194
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   195
.. sourcecode:: python
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   196
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   197
 @objectify_selector
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   198
 def foo_authenticated(cls, req, rset=None, **kwargs):
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   199
     if hasattr(req.cnx, 'foo_user') and req.foo_user:
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   200
         return 1
20a7399ed58d [doc/book] complete section on authentication plugins
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6313
diff changeset
   201
     return 0