1repoze.who Changelog
2====================
3
42.4 (2020-06-03)
5----------------
6
7- Add upport for Python 3.6, 3.7, and 3.8.
8
9- Drop support for Python 3.3.
10
11- Fix travis configuration.
12
13- Add ``samesite`` option to AuthTktCookiePlugin constructor.
14  If this is passed, it should be a string, and it will be used
15  to compose the Set-Cookie header's "SameSite" value, e.g.
16  if you pass ``samesite="Strict"`` into the constructor,
17  the cookie value for the auth tkt cooke will contain
18  ``SameSite=Strict``.
19
202.3 (2016-05-31)
21----------------
22
23- Add support for Python 3.4, Python 3.5, and PyPy3.
24
25- Drop support for Python 2.6 and 3.2.
26
27- ``middleware``:  avoid passing extracted ``identity`` to ``remember``
28  during egress (the app may have called ``api.forget()``).  See #21.
29
30- ``_auth_tkt`` / ``plugins.auth_tkt``:  add support for any hash algorithm
31  supported by the ``hashlib`` module in Python's standard library.
32  Fixes #22 via #23.
33
34- ``plugins.auth_tkt``:  Fix storage of "userdata" to save dict.  Fixes
35  #14 via #18.
36
37- middleware:  avoid UnboundLocalError when wrapped generater yields no
38  items.  See:  http://bugs.repoze.org/issue184
39
40- Make cookie expiration date RFC-2616 compliant (independent of locale,
41  including 'GMT' zone). See #11.
42
432.2 (2013-05-17)
44----------------
45
46- Parse INI-file configuration using ``SafeConfigParser``:  allows
47  escaping the ``'%'`` so that e.g. a query template using for a DB-API
48  connection using ``pyformat`` preserves the template.
49
50- Added support for Python 3.3, PyPy.
51
52
532.1 (2013-03-20)
54----------------
55
56- ``_compat`` module:  tolerate missing ``CONTENT_TYPE`` key in the WSGI
57  environment.  Thanks to Dag Hoidal for the patch.
58
59- ``htpasswd`` plugin:  add a ``sha1_check`` checker function (the ``crypt``
60  module is not available on Windows).  Thanks to Chandrashekar Jayaraman
61  for the patch.
62
63- Documentation typo fixes from Carlos de la Guardia and Atsushi Odagiri.
64
65
662.1b1 (2012-11-05)
67------------------
68
69- Ported to Py3k using the "compatible subset" mode.
70  - Dropped support for Python < 2.6.x.
71  - Dropped dependency on Paste (forking some code from it).
72  - Added dependency on WebOb instead.
73  Thanks to Atsushi Odagiri (aodag) for the initial effort.
74
75
762.0 (2011-09-28)
77----------------
78
79- ``auth_tkt`` plugin:  strip any port number from the 'Domain' of generated
80  cookies.  http://bugs.repoze.org/issue66
81
82- Further harden middleware, calling ``close()`` on the iterable even if
83  raising an exception for a missing challenger.
84  http://bugs.repoze.org/issue174
85
86
872.0b1 (2011-05-24)
88------------------
89
90- Enabled standard use of logging module's configuration mechanism.
91  See http://docs.python.org/dev/howto/logging.html#configuring-logging-for-a-library
92  Thanks to jgoldsmith for the patch: http://bugs.repoze.org/issue178
93
94
95- ``repoze.who.plugins.htpasswd``:  defend against timing-based attacks.
96
97
982.0a4 (2011-02-02)
99------------------
100
101- Ensure that the middleware calls ``close()`` (if it exists) on the
102  iterable returned from thw wrapped application, as required by PEP 333.
103  http://bugs.repoze.org/issue174
104
105- Make ``make_api_factory_with_config`` tolerant of invalid filenames /
106  content for the config file:  in such cases, the API factory will have
107  *no* configured plugins or policies:  it will only be useful for retrieving
108  the API from an environment populated by middleware.
109
110- Fix bug in ``repoze.who.api`` where the ``remember()`` or ``forget()``
111  methods could return a None if the identifier plugin returned a None.
112
113- Fix ``auth_tkt`` plugin to not hand over tokens as strings to paste. See
114  http://lists.repoze.org/pipermail/repoze-dev/2010-November/003680.html
115
116- Fix ``auth_tkt`` plugin to add "secure" and "HttpOnly" to cookies when
117  configured with ``secure=True``:  these attributes prevent the browser from
118  sending cookies over insecure channels, which could be vulnerable to some
119  XSS attacks.
120
121- Avoid propagating unicode 'max_age' value into cookie headers.  See
122  https://bugs.launchpad.net/bugs/674123 .
123
124- Added a single-file example BFG application demonstrating the use of
125  the new 'login' and 'logout' methods of the API object.
126
127- Add ``login`` and ``logout`` methods to the ``repoze.who.api.API`` object,
128  as a convenience for application-driven login / logout code, which would
129  otherwise need to use private methods of the API, and reach down into
130  its plugins.
131
132
1332.0a3 (2010-09-30)
134------------------
135
136- Deprecated the following plugins, moving their modules, tests, and docs
137  to a new project, ``repoze.who.deprecatedplugins``:
138
139  - ``repoze.who.plugins.cookie.InsecureCookiePlugin``
140
141  - ``repoze.who.plugins.form.FormPlugin``
142
143  - ``repoze.who.plugins.form.RedirectingFormPlugin``
144
145- Made the ``repoze.who.plugins.cookie.InsecureCookiePlugin`` take a
146  ``charset`` argument, and use to to encode / decode login and password.
147  See http://bugs.repoze.org/issue155
148
149- Updated ``repoze.who.restrict`` to return headers as a list, to keep
150  ``wsgiref`` from complaining.
151
152- Helped default request classifier cope with xml submissions with an
153  explicit charset defined: http://bugs.repoze.org/issue145 (Lorenzo
154  M. Catucci)
155
156- Corrected the handling of type and subtype when matching an XML post
157  to ``xmlpost`` in the default classifier, which, according to RFC
158  2045, must be matched case-insensitively:
159  http://bugs.repoze.org/issue145 (Lorenzo M. Catucci)
160
161- Added ``repoze.who.config:make_api_factory_with_config``, a convenience
162  method for applications which want to set up their own API Factory from
163  a configuration file.
164
165- Fixed example call to ``repoze.who.config:make_middleware_with_config``
166  (added missing ``global_config`` argument).  See
167  http://bugs.repoze.org/issue114
168
169
1702.0a2 (2010-03-25)
171------------------
172
173Bugs Fixed
174~~~~~~~~~~
175
176- Fixed failure to pass substution values in log message string formatting
177  for ``repoze.who.api:API.challenge``.  Fix included adding tests for all
178  logging done by the API object.  See http://bugs.repoze.org/issue122
179
180Backward Incompatibilities
181~~~~~~~~~~~~~~~~~~~~~~~~~~
182
183- Adjusted logging level for some lower-level details from ``info``
184  to ``debug``.
185
186
187
1882.0a1 (2010-02-24)
189------------------
190
191Features
192~~~~~~~~
193
194- Restored the ability to create the middleware using the old ``classifier``
195  argument.  That argument is now a deprecated-but-will-work-forever alias for
196  ``request_classifier``.
197
198- The ``auth_tkt`` plugin now implements the ``IAuthenticator`` interface,
199  and should normally be used both as an ``IIdentifier`` and an
200  ``IAuthenticator``.
201
202- Factored out the API of the middleware object to make it useful from
203  within the application.  Applications using ``repoze.who``` now fall into
204  one of three catgeories:
205
206  - "middleware-only" applications are configured with middleware, and
207    use either ``REMOTE_USER`` or ``repoze.who.identity`` from the environment
208    to determing the authenticated user.
209
210  - "bare metal" applications use no ``repoze.who`` middleware at all:
211    instead, they configure and an ``APIFactory`` object at startup, and
212    use it to create an ``API`` object when needed on a per-request basis.
213
214  - "hybrid" applications are configured with ``repoze.who`` middleware,
215    but use a new library function to fetch the ``API`` object from the
216    environ, e.g. to permit calling ``remember`` after a signup or successful
217    login.
218
219Bugs Fixed
220~~~~~~~~~~
221
222- Fix http://bugs.repoze.org/issue102: when no challengers existed,
223  logging would cause an exception.
224
225- Remove ``ez_setup.py`` and dependency on it in setup.py (support
226  distribute).
227
228Backward Incompatibilities
229~~~~~~~~~~~~~~~~~~~~~~~~~~
230
231- The middleware used to allow identifier plugins to "pre-authenticate"
232  an identity.  This feature is no longer supported: the ``auth_tkt``
233  plugin, which used to use the feature, is now configured to work as
234  an authenticator plugin (as well as an identifier).
235
236- The ``repoze.who.middleware:PluggableAuthenticationMiddleware`` class
237  no longer has the following (non-API) methods (now made API methods
238  of the ``repoze.who.api:API`` class):
239
240  - ``add_metadata``
241  - ``authenticate``
242  - ``challenge``
243  - ``identify``
244
245- The following (non-API) functions moved from ``repoze.who.middleware`` to
246  ``repoze.who.api``:
247
248  - ``make_registries``
249  - ``match_classification``
250  - ``verify``
251
252
253
2541.0.18 (2009-11-05)
255-------------------
256
257- Issue #104:  AuthTkt plugin was passing an invalid cookie value in
258  headers from ``forget``, and was not setting the ``Max-Age`` and
259  ``Expires`` attributes of those cookies.
260
261
262
2631.0.17 (2009-11-05)
264-------------------
265
266- Fixed the ``repoze.who.plugins.form.make_plugin`` factory's ``formcallable``
267  argument handling, to allow passing in a dotted name (e.g., from a config
268  file).
269
270
271
2721.0.16 (2009-11-04)
273-------------------
274
275- Exposed ``formcallable`` argument for ``repoze.who.plugins.form.FormPlugin``
276  to the callers of the ``repoze.who.plugins.form.make_plugin`` factory.
277  Thanks to Roland Hedburg for the report.
278
279- Fixed an issue that caused the following symptom when using the
280  ini configuration parser::
281
282   TypeError: _makePlugin() got multiple values for keyword argument 'name'
283
284  See http://bugs.repoze.org/issue92 for more details.  Thanks to vaab
285  for the bug report and initial fix.
286
287
2881.0.15 (2009-06-25)
289-------------------
290
291- If the form post value ``max_age`` exists while in the ``identify``
292  method is handling the ``login_handler_path``, pass the max_age
293  value in the returned identity dictionary as ``max_age``.  See the
294  below bullet point for why.
295
296- If the ``identity`` dict passed to the ``auth_tkt`` ``remember``
297  method contains a ``max_age`` key with a string (or integer) value,
298  treat it as a cue to set the ``Max-Age`` and ``Expires`` headers in
299  the returned cookies.  The cookie ``Max-Age`` is set to the value
300  and the ``Expires`` is computed from the current time.
301
302
3031.0.14 (2009-06-17)
304-------------------
305
306- Fix test breakage on Windows.  See http://bugs.repoze.org/issue79 .
307
308- Documented issue with using ``include_ip`` setting in the ``auth_tkt``
309  plugin.  See http://bugs.repoze.org/issue81 .
310
311- Added 'passthrough_challenge_decider', which avoids re-challenging 401
312  responses which have been "pre-challenged" by the application.
313
314- One-hundred percent unit test coverage.
315
316- Add ``timeout`` and ``reissue_time`` arguments to the auth_tkt
317  identifier plugin, courtesty of Paul Johnston.
318
319- Add a ``userid_checker`` argument to the auth_tkt identifier plugin,
320  courtesty of Gustavo Narea.
321
322  If ``userid_checker`` is provided, it must be a dotted Python name
323  that resolves to a function which accepts a userid and returns a
324  boolean True or False, indicating whether that user exists in a
325  database.  This is a workaround.  Due to a design bug in repoze.who,
326  the only way who can check for user existence is to use one or more
327  IAuthenticator plugin ``authenticate`` methods.  If an
328  IAuthenticator's ``authenticate`` method returns true, it means that
329  the user exists.  However most IAuthenticator plugins expect *both*
330  a username and a password, and will return False unconditionally if
331  both aren't supplied.  This means that an authenticator can't be
332  used to check if the user "only" exists.  The identity provided by
333  an auth_tkt does not contain a password to check against.  The
334  actual design bug in repoze.who is this: when a user presents
335  credentials from an auth_tkt, he is considered "preauthenticated".
336  IAuthenticator.authenticate is just never called for a
337  "preauthenticated" identity, which works fine, but it means that the
338  user will be considered authenticated even if you deleted the user's
339  record from whatever database you happen to be using.  However, if
340  you use a userid_checker, you can ensure that a user exists for the
341  auth_tkt supplied userid.  If the userid_checker returns False, the
342  auth_tkt credentials are considered "no good".
343
344
3451.0.13 (2009-04-24)
346-------------------
347
348- Added a paragraph to ``IAuthenticator`` docstring, documenting that plugins
349  are allowed to add keys to the ``identity`` dictionary (e.g., to save a
350  second database query in an ``IMetadataProvider`` plugin).
351
352- Patch supplied for issue #71 (http://bugs.repoze.org/issue71)
353  whereby a downstream app can return a generator, relying on an
354  upstream component to call start_response.  We do this because the
355  challenge decider needs the status and headers to decide what to do.
356
357
3581.0.12 (2009-04-19)
359-------------------
360- auth_tkt plugin tried to append REMOTE_USER_TOKENS data to
361  existing tokens data returned by auth_tkt.parse_tkt; this was
362  incorrect; just overwrite.
363
364- Extended auth_tkt plugin factory to allow passing secret in a separate
365  file from the main config file.  See http://bugs.repoze.org/issue40 .
366
367
3681.0.11 (2009-04-10)
369-------------------
370
371- Fix auth_tkt plugin; cookie values are now quoted, making it possible
372  to put spaces and other whitespace, etc in usernames. (thanks to Michael
373  Pedersen).
374
375- Fix corner case issue of an exception raised when attempting to log
376  when there are no identifiers or authenticators.
377
378
3791.0.10 (2009-01-23)
380-------------------
381
382- The RedirectingFormPlugin now passes along SetCookie headers set
383  into the response by the application within the NotFound response
384  (fixes TG2 "flash" issue).
385
386
3871.0.9 (2008-12-18)
388------------------
389
390- The RedirectingFormPlugin now attempts to find a header named
391  ``X-Authentication-Failure-Reason`` among the response headers set
392  by the application when a challenge is issued.  If a value for this
393  header exists (and is non-blank), the value is attached to the
394  redirect URL's query string as the ``reason`` parameter (or a
395  user-settable key).  This makes it possible for downstream
396  applications to issue a response that initiates a challenge with
397  this header and subsequently display the reason in the login form
398  rendered as a result of the challenge.
399
400
4011.0.8 (2008-12-13)
402------------------
403
404- The ``PluggableAuthenticationMiddleware`` constructor accepts a
405  ``log_stream`` argument, which is typically a file.  After this
406  release, it can also be a PEP 333 ``Logger`` instance; if it is a
407  PEP 333 ``Logger`` instance, this logger will be used as the
408  repoze.who logger (instead of one being constructed by the
409  middleware, as was previously always the case).  When the
410  ``log_stream`` argument is a PEP 333 Logger object, the
411  ``log_level`` argument is ignored.
412
413
4141.0.7 (2008-08-28)
415------------------
416
417- ``repoze.who`` and ``repoze.who.plugins`` were not added to the
418  ``namespace_packages`` list in setup.py, potentially making 1.0.6 a
419  brownbag release, given that making these packages namespace
420  packages was the only reason for its release.
421
422
4231.0.6 (2008-08-28)
424------------------
425
426- Make repoze.who and repoze.who.plugins into namespace packages
427  mainly so we can allow plugin authors to distribute packages in the
428  repoze.who.plugins namespace.
429
430
4311.0.5 (2008-08-23)
432------------------
433
434- Fix auth_tkt plugin to set the same cookies in its ``remember``
435  method that it does in its ``forget`` method.  Previously, logging
436  out and relogging back in to a site that used auth_tkt identifier
437  plugin was slightly dicey and would only work sometimes.
438
439- The FormPlugin plugin has grown a redirect-on-unauthorized feature.
440  Any response from a downstream application that causes a challenge
441  and includes a Location header will cause a redirect to the value of
442  the Location header.
443
444
4451.0.4 (2008-08-22)
446------------------
447
448- Added a key to the '[general]' config section: ``remote_user_key``.
449  If you use this key in the config file, it tells who to 1) not
450  perform any authentication if it exists in the environment during
451  ingress and 2) to set the key in the environment for the downstream
452  app to use as the REMOTE_USER variable.  The default is
453  ``REMOTE_USER``.
454
455- Using unicode user ids in combination with the auth_tkt plugin would
456  cause problems under mod_wsgi.
457
458- Allowed 'cookie_path' argument to InsecureCookiePlugin (and config
459  constructor).  Thanks to Gustavo Narea.
460
461
4621.0.3 (2008-08-16)
463------------------
464
465- A bug in the middleware's ``authenticate`` method made it impossible
466  to authenticate a user with a userid that was null (e.g. 0, False),
467  which are valid identifiers.  The only invalid userid is now None.
468
469- Applied patch from Olaf Conradi which logs an error when an invalid
470  filename is passed to the HTPasswdPlugin.
471
472
4731.0.2 (2008-06-16)
474------------------
475
476- Fix bug found by Chris Perkins: the auth_tkt plugin's "remember"
477  method didn't handle userids which are Python "long" instances
478  properly.  Symptom: TypeError: cannot concatenate 'str' and 'long'
479  objects in "paste.auth.auth_tkt".
480
481- Added predicate-based "restriction" middleware support
482  (repoze.who.restrict), allowing configuratio-driven authorization as
483  a WSGI filter.  One example predicate, 'authenticated_predicate', is
484  supplied, which requires that the user be authenticated either via
485  'REMOTE_USER' or via 'repoze.who.identity'.  To use the filter to
486  restrict access::
487
488     [filter:authenticated_only]
489     use = egg:repoze.who#authenticated
490
491   or::
492
493     [filter:some_predicate]
494     use = egg:repoze.who#predicate
495     predicate = my.module:some_predicate
496     some_option = a value
497
498
4991.0.1 (2008-05-24)
500------------------
501
502- Remove dependency-link to dist.repoze.org to prevent easy_install
503  from inserting that path into its search paths (the dependencies are
504  available from PyPI).
505
506
5071.0 (2008-05-04)
508-----------------
509
510- The plugin at plugins.form.FormPlugin didn't redirect properly after
511  collecting identification information.  Symptom: a downstream app
512  would receive a POST request with a blank body, which would
513  sometimes result in a Bad Request error.
514
515- Fixed interface declarations of
516  'classifiers.default_request_classifier' and
517  'classifiers.default_password_compare'.
518
519- Added actual config-driven middleware factory,
520  'config.make_middleware_with_config'
521
522- Removed fossilized 'who_conf' argument from plugin factory functions.
523
524- Added ConfigParser-based WhoConfig, implementing the spec outlined at
525  http://www.plope.com/static/misc/sphinxtest/intro.html#middleware-configuration-via-config-file,
526  with the following changes:
527
528  - "Bare" plugins (requiring no configuration options) may be specified
529     as either egg entry points (e.g., 'egg:distname#entry_point_name') or
530     as dotted-path-with-colon (e.g., 'dotted.name:object_id').
531
532  - Therefore, the separator between a plugin and its classifier is now
533    a semicolon, rather than a colon. E.g.::
534
535     [plugins:id_plugin]
536     use = egg:another.package#identify_with_frobnatz
537     frobnatz = baz
538
539     [identifiers]
540     plugins =
541       egg:my.egg#identify;browser
542       dotted.name:identifier
543       id_plugin
544
545
5460.9.1 (2008-04-27)
547------------------
548
549- Fix auth_tkt plugin to be able to encode and decode integer user
550  ids.
551
552
5530.9 (2008-04-01)
554----------------
555
556- Fix bug introduced in FormPlugin in 0.8 release (rememberer headers
557  not set).
558
559- Add PATH_INFO to started and ended log info.
560
561- Add a SQLMetadataProviderPlugin (in plugins/sql).
562
563- Change constructor of SQLAuthenticatorPlugin: it now accepts only
564  "query", "conn_factory", and "compare_fn".  The old constructor
565  accepted a DSN, but some database systems don't use DBAPI DSNs.  The
566  new constructor accepts no DSN; the conn_factory is assumed to do
567  all the work to make a connection, including knowing the DSN if one
568  is required.  The "conn_factory" should return something that, when
569  called with no arguments, returns a database connection.
570
571- The "make_plugin" helper in plugins/sql has been renamed
572  "make_authenticator_plugin".  When called, this helper will return a
573  SQLAuthenticatorPlugin.  A bit of helper logic in the
574  "make_authenticator_plugin" allows a connection factory to be
575  computed.  The top-level callable referred to by conn_factory in
576  this helper should return a function that, when called with no
577  arguments, returns a datbase connection.  The top-level callable
578  itself is called with "who_conf" (global who configuration) and any
579  number of non-top-level keyword arguments as they are passed into
580  the helper, to allow for a DSN or URL or whatever to be passed in.
581
582- A "make_metatata_plugin" helper has been added to plugins/sql. When
583  called, this will make a SQLMetadataProviderPlugin.  See the
584  implementation for details.  It is similar to the
585  "make_authenticator_plugin" helper.
586
587
5880.8 (2008-03-27)
589----------------
590
591- Add a RedirectingFormIdentifier plugin.  This plugin is willing to
592  redirect to an external (or downstream application) login form to
593  perform identification.  The external login form must post to the
594  "login_handler_path" of the plugin (optimally with a "came_from"
595  value to tell the plugin where to redirect the response to if the
596  authentication works properly).  The "logout_handler_path" of this
597  plugin can be visited to perform a logout.  The "came_from" value
598  also works there.
599
600- Identifier plugins are now permitted to set a key in the environment
601  named 'repoze.who.application' on ingress (in 'identify').  If an
602  identifier plugin does so, this application is used instead of the
603  "normal" downstream application.  This feature was added to more
604  simply support the redirecting form identifier plugin.
605
606
6070.7 (2008-03-26)
608----------------
609
610- Change the IMetadataProvider interface: this interface used to have
611  a "metadata" method which returned a dictionary.  This method is not
612  part of that API anymore.  It's been replaced with an "add_metadata"
613  method which has the signature::
614
615    def add_metadata(environ, identity):
616        """
617        Add metadata to the identity (which is a dictionary)
618        """
619
620   The return value is ignored.  IMetadataProvider plugins are now
621   assumed to be responsible for 'scribbling' directly on the identity
622   that is passed in (it's a dictionary).  The user id can always be
623   retrieved from the identity via identity['repoze.who.userid'] for
624   metadata plugins that rely on that value.
625
626
6270.6 (2008-03-20)
628----------------
629
630- Renaming: repoze.pam is now repoze.who
631
632- Bump ez_setup.py version.
633
634- Add IMetadataProvider plugin type.  Chris says 'Whit rules'.
635
636
6370.5 (2008-03-09)
638----------------
639
640- Allow "remote user key" (default: REMOTE_USER) to be overridden
641  (pass in remote_user_key to middleware constructor).
642
643- Allow form plugin to override the default form.
644
645- API change: IIdentifiers are no longer required to put both 'login'
646  and 'password' in a returned identity dictionary.  Instead, an
647  IIdentifier can place arbitrary key/value pairs in the identity
648  dictionary (or return an empty dictionary).
649
650- API return value change: the "failure" identity which IIdentifiers
651  return is now None rather than an empty dictionary.
652
653- The IAuthenticator interface now specifies that IAuthenticators must
654  not raise an exception when evaluating an identity that does not
655  have "expected" key/value pairs (e.g. when an IAuthenticator that
656  expects login and password inspects an identity returned by an
657  IP-based auth system which only puts the IP address in the
658  identity); instead they fail gracefully by returning None.
659
660- Add (cookie) "auth_tkt" identification plugin.
661
662- Stamp identity dictionaries with a userid by placing a key named
663  'repoze.pam.userid' into the identity for each authenticated
664  identity.
665
666- If an IIdentifier plugin inserts a 'repoze.pam.userid' key into the
667  identity dictionary, consider this identity "preauthenticated".  No
668  authenticator plugins will be asked to authenticate this identity.
669  This is designed for things like the recently added auth_tkt plugin,
670  which embeds the user id into the ticket.  This effectively alllows
671  an IIdentifier plugin to become an IAuthenticator plugin when
672  breaking apart the responsibility into two separate plugins is
673  "make-work".  Preauthenticated identities will be selected first
674  when deciding which identity to use for any given request.
675
676- Insert a 'repoze.pam.identity' key into the WSGI environment on
677  ingress if an identity is found.  Its value will be the identity
678  dictionary related to the identity selected by repoze.pam on
679  ingress.  Downstream consumers are allowed to mutate this
680  dictionary; this value is passed to "remember" and "forget", so its
681  main use is to do a "credentials reset"; e.g. a user has changed his
682  username or password within the application, but we don't want to
683  force him to log in again after he does so.
684
685
6860.4 (03-07-2008)
687----------------
688
689- Allow plugins to specify a classifiers list per interface (instead
690  of a single classifiers list per plugin).
691
692
6930.3 (03-05-2008)
694----------------
695
696- Make SQLAuthenticatorPlugin's default_password_compare use hexdigest
697  sha instead of base64'ed binary sha for simpler conversion.
698
699
7000.2 (03-04-2008)
701----------------
702
703- Added SQLAuthenticatorPlugin (see plugins/sql.py).
704
705
7060.1 (02-27-2008)
707----------------
708
709- Initial release (no configuration file support yet).
710