[Checkins] SVN: z3c.authviewlet/trunk/ Adapted test set up to the changes in `z3c.layer.pagelet` 1.9 thus requiring at least this version now.

Michael Howitz mh at gocept.com
Wed Oct 13 09:41:26 EDT 2010


Log message for revision 117514:
  Adapted test set up to the changes in `z3c.layer.pagelet` 1.9 thus requiring at least this version now.
  

Changed:
  U   z3c.authviewlet/trunk/CHANGES.txt
  U   z3c.authviewlet/trunk/buildout.cfg
  U   z3c.authviewlet/trunk/setup.py
  U   z3c.authviewlet/trunk/src/z3c/authviewlet/README.txt
  U   z3c.authviewlet/trunk/src/z3c/authviewlet/tests/ftesting.zcml

-=-
Modified: z3c.authviewlet/trunk/CHANGES.txt
===================================================================
--- z3c.authviewlet/trunk/CHANGES.txt	2010-10-13 13:31:03 UTC (rev 117513)
+++ z3c.authviewlet/trunk/CHANGES.txt	2010-10-13 13:41:25 UTC (rev 117514)
@@ -1,10 +1,11 @@
 Changes
 -------
 
-0.7.1 (unreleased)
+0.8.0 (unreleased)
 ~~~~~~~~~~~~~~~~~~
 
-- Nothing changed yet.
+- Adapted test set up to the changes in `z3c.layer.pagelet` 1.9 thus
+  requiring at least this version now.
 
 
 0.7.0 (2009-12-27)

Modified: z3c.authviewlet/trunk/buildout.cfg
===================================================================
--- z3c.authviewlet/trunk/buildout.cfg	2010-10-13 13:31:03 UTC (rev 117513)
+++ z3c.authviewlet/trunk/buildout.cfg	2010-10-13 13:41:25 UTC (rev 117514)
@@ -5,7 +5,6 @@
 [test]
 recipe = zc.recipe.testrunner
 eggs = z3c.authviewlet [test]
-       z3c.layer.pagelet [test]
 
 [checker]
 recipe = lovely.recipe:importchecker

Modified: z3c.authviewlet/trunk/setup.py
===================================================================
--- z3c.authviewlet/trunk/setup.py	2010-10-13 13:31:03 UTC (rev 117513)
+++ z3c.authviewlet/trunk/setup.py	2010-10-13 13:41:25 UTC (rev 117514)
@@ -54,15 +54,16 @@
     namespace_packages = ['z3c',],
     extras_require = dict(
         test = [
+            'z3c.layer.pagelet [test] >= 1.9',
+            'zope.app.authentication',
+            'zope.app.testing',
             'zope.testbrowser',
-            'z3c.layer.pagelet',
-            'zope.app.testing',
             'zope.testing',
             ],
         ),
     install_requires = [
         'setuptools',
-        'z3c.layer.pagelet',
+        'z3c.layer.pagelet >= 1.9',
         'zope.authentication',
         'zope.component',
         'zope.i18n',

Modified: z3c.authviewlet/trunk/src/z3c/authviewlet/README.txt
===================================================================
--- z3c.authviewlet/trunk/src/z3c/authviewlet/README.txt	2010-10-13 13:31:03 UTC (rev 117513)
+++ z3c.authviewlet/trunk/src/z3c/authviewlet/README.txt	2010-10-13 13:41:25 UTC (rev 117514)
@@ -1,613 +1,613 @@
-Login and logout
-----------------
-
-Login and logout work both for basic auth and cookie auth.
-
-
-Setup
-~~~~~
-
-The layout page template has to include two content providers (viewlet
-mangers):
-
-  - ``login-logout-head`` inside the head tag to get automatic
-    redirects and JavaScript code which does the logout for basic
-    auth and
-
-  - ``login-logout`` inside the body tag to get login and logout links.
-
-The sample template looks like this:
-
-  >>> import os.path
-  >>> template_path = os.path.join(os.path.dirname(__file__), "tests",
-  ...     "login-logout-template.pt")
-  >>> print file(template_path, "r").read()
-  <!DOCTYPE ...>
-  <html ...>
-    <head>
-      <title>PageletTest</title>
-      <tal:block replace="structure provider:login-logout-head" />
-    </head>
-    <body>
-      <tal:block replace="structure provider:login-logout" />
-      <tal:block replace="structure provider:pagelet" />
-    </body>
-  </html>
-
-This template is registered for the ``IContainer`` interface in
-``ftesting.zcml``. After creating a container the template is
-used when browsing the container:
-
-  >>> from zope.container.btree import BTreeContainer
-  >>> getRootFolder()['container'] = BTreeContainer()
-
-Basic auth
-~~~~~~~~~~
-
-When the user is not logged in the login link is displayed:
-
-  >>> from zope.testbrowser.testing import Browser
-  >>> skinURL = 'http://localhost/++skin++PageletTestSkin/'
-  >>> browser = Browser()
-  >>> browser.handleErrors = False
-  >>> browser.open(skinURL + 'container/@@default.html')
-  >>> browser.url
-  'http://localhost/++skin++PageletTestSkin/container/@@default.html'
-  >>> print browser.contents
-  <!DOCTYPE ...>
-  <html ...>
-    <head>
-      <title>PageletTest</title>
-    </head>
-    <body>
-      <a href="http://localhost/++skin++PageletTestSkin/container/@@login.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html">Login</a>
-    </body>
-  </html>
-
-Selecting the link leads to the login page, as we use basic auth here,
-we get an HTTP error 401 (unauthorized):
-
-  >>> login_url = browser.getLink('Login').url
-  >>> browser.getLink('Login').click()
-  Traceback (most recent call last):
-  httperror_seek_wrapper: HTTP Error 401: Unauthorized
-  >>> browser.url
-  'http://localhost/++skin++PageletTestSkin/container/@@login.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html'
-
-When adding correct credentials we get authorized:
-
-  >>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
-  >>> browser.reload()
-
-We are redirected to the page where we selected the login link. After
-logging in the login link is no longer displayed. As we did not
-specify that logout is supported, no logout link is displayed:
-
-  >>> browser.url
-  'http://localhost/++skin++PageletTestSkin/container/@@default.html'
-  >>> print browser.contents
-  <!DOCTYPE ...>
-  <html ...>
-    <head>
-      <title>PageletTest</title>
-    </head>
-    <body>
-    </body>
-  </html>
-
-Calling the login URL again leads directly to the page referred in nextURL:
-
-  >>> browser.open(login_url)
-  >>> browser.url
-  'http://localhost/++skin++PageletTestSkin/container/@@default.html'
-  >>> print browser.contents
-  <!DOCTYPE ...>
-  <html ...>
-    <head>
-      <title>PageletTest</title>
-    </head>
-    <body>
-    </body>
-  </html>
-
-Calling the login URL again without the query parameter leeds to a
-confirmation page telling that login was successfull:
-
-  >>> browser.open(login_url.split('?')[0])
-  >>> browser.url
-  'http://localhost/++skin++PageletTestSkin/container/@@login.html'
-  >>> print browser.contents
-  <!DOCTYPE ...>
-  <html ...>
-  <head>
-  <title>PageletTestLayout</title>
-  </head>
-  <body>
-    <div>
-     <h1>Login successful!</h1>
-     <p style="font-size: 200%"> You are now logged in as <em>Manager</em>. </p>
-     <a href=".">Back to the main page.</a>
-    </div>
-  </body>
-  </html>
-
-Selecting the ``Back to the main page.`` link send the user back to
-the default view of the container. (``ftesting.zcml`` defines
-``@@default.html`` as the default view.):
-
-  >>> browser.getLink('Back to the main page.').click()
-  >>> browser.url
-  'http://localhost/++skin++PageletTestSkin/container/'
-  >>> print browser.contents
-  <!DOCTYPE ...>
-  <html ...>
-    <head>
-      <title>PageletTest</title>
-    </head>
-    <body>
-    </body>
-  </html>
-
-
-Providing an ``ILogoutSupported`` adapter leads to a logout link being
-displayed:
-
-  >>> from zope.app.testing import ztapi
-  >>> import zope.interface
-  >>> import zope.authentication.logout
-  >>> import zope.authentication.interfaces
-  >>> ztapi.provideAdapter(
-  ...     zope.interface.Interface,
-  ...     zope.authentication.interfaces.ILogoutSupported,
-  ...     zope.authentication.logout.LogoutSupported)
-  >>> browser.reload()
-  >>> browser.url
-  'http://localhost/++skin++PageletTestSkin/container/'
-  >>> print browser.contents
-  <!DOCTYPE ...>
-  <html ...>
-    <head>
-      <title>PageletTest</title>
-    </head>
-    <body>
-      <a href="http://localhost/++skin++PageletTestSkin/container/@@logout.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html">Logout</a>
-    </body>
-  </html>
-
-Logout is done using JavaScript and a redirect. zope.testbrowser
-follows the redirects even if they use the meta tag instead of the
-status code. So I have to use a non API call to change this behavior
-to show the file contents:
-
-  >>> browser.mech_browser.set_handle_refresh(False)
-
-As testbrowser is not able to execute JavaScript the user remains
-authenticated:
-
-  >>> logout_url = browser.getLink('Logout').url
-  >>> browser.getLink('Logout').click()
-  >>> browser.url
-  'http://localhost/++skin++PageletTestSkin/container/@@logout.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html'
-  >>> print browser.contents
-  <!DOCTYPE ...>
-  <html ...>
-    <head>
-      <title>PageletTest</title>
-      <script type="text/javascript"><!--
-    // clear HTTP Authentication
-    ...
-    //-->
-  </script>
-  <meta http-equiv="refresh"
-        content="0;url=http://localhost/++skin++PageletTestSkin/container/@@default.html" />
-    </head>
-    <body>
-      <a href="http://localhost/++skin++PageletTestSkin/container/@@logout.html/@@logout.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40logout.html">Logout</a>
-      <div>
-    <h1>You are being redirected!</h1>
-    <p style="font-size: 150%">
-      <a href="http://localhost/++skin++PageletTestSkin/container/@@default.html">
-        If you see this screen for more than 5 seconds, click here.
-      </a>
-    </p>
-  </div>
-    </body>
-  </html>
-
-Calling the logout URL again after logout (simulated using a new
-browser instance) leads directly to the page referred in nextURL:
-
-  >>> browser2 = Browser(logout_url)
-  >>> browser2.url
-  'http://localhost/++skin++PageletTestSkin/container/@@default.html'
-  >>> print browser2.contents
-  <!DOCTYPE ...>
-  <html ...>
-    <head>
-      <title>PageletTest</title>
-    </head>
-    <body>
-      <a href="http://localhost/++skin++PageletTestSkin/container/@@login.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html">Login</a>
-    </body>
-  </html>
-
-Calling the logout URL again without the query parameter leeds to a
-confirmation page telling that logout was successfull:
-
-  >>> browser2.open(logout_url.split('?')[0])
-  >>> browser2.url
-  'http://localhost/++skin++PageletTestSkin/container/@@logout.html'
-  >>> print browser2.contents
-  <!DOCTYPE ...>
-  <html ...>
-    <head>
-      <title>PageletTest</title>
-      <script type="text/javascript"><!--
-    // clear HTTP Authentication
-    ...
-    //-->
-  </script>
-    </head>
-    <body>
-      <a href="http://localhost/++skin++PageletTestSkin/container/logout.html/@@login.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40logout.html">Login</a>
-      <div>
-    <h1>Logout successful!</h1>
-    <p style="font-size: 200%">
-      You are now logged out.
-    </p>
-    <a href=".">Back to the main page.</a>
-  </div>
-    </body>
-  </html>
-
-
-Cookie auth
-~~~~~~~~~~~
-
-To do cookie auth we have to set up a pluggable auth utility (PAU)
-with a authenticator plug-in (principal folder) first:
-
-  >>> from zope.authentication.interfaces import IAuthentication
-  >>> from zope.app.authentication.interfaces import IAuthenticatorPlugin
-  >>> from zope.app.authentication.authentication import PluggableAuthentication
-  >>> from zope.app.authentication.principalfolder import PrincipalFolder
-  >>> from zope.site import site
-
-  >>> root = getRootFolder()
-  >>> root['principal_folder'] = PrincipalFolder()
-  >>> sm = root.getSiteManager()
-  >>> sm.registerUtility(
-  ...     root['principal_folder'], IAuthenticatorPlugin, 'principal_folder')
-
-  >>> root['auth'] = PluggableAuthentication()
-  >>> sm.registerUtility(root['auth'], IAuthentication, '')
-  >>> root['auth'].credentialsPlugins = (u'Session Credentials',)
-  >>> root['auth'].authenticatorPlugins = (u'principal_folder',)
-
-We need a principal inside the principal folder:
-
-  >>> from zope.app.authentication.principalfolder import InternalPrincipal
-  >>> root['principal_folder']['1'] = InternalPrincipal(
-  ...     'tester', 'tpass', 'Tester')
-
-
-We use a new browser, so the principal is not logged in and the login
-link is displayed:
-
-  >>> browser = Browser()
-  >>> browser.open(skinURL + 'container/@@default.html')
-  >>> browser.url
-  'http://localhost/++skin++PageletTestSkin/container/@@default.html'
-  >>> print browser.contents
-  <!DOCTYPE ...>
-  <html ...>
-    <head>
-      <title>PageletTest</title>
-    </head>
-    <body>
-      <a href="http://localhost/++skin++PageletTestSkin/container/@@login.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html">Login</a>
-    </body>
-  </html>
-
-Selecting the link leads to the login page:
-
-  >>> login_url = browser.getLink('Login').url
-  >>> browser.getLink('Login').click()
-  >>> browser.url
-  'http://localhost/++skin++PageletTestSkin/@@loginForm.html?camefrom=%2F%2B%2Bskin%2B%2BPageletTestSkin%2Fcontainer%2F%40%40login.html%3FnextURL%3Dhttp%253A%2F%2Flocalhost%2F%252B%252Bskin%252B%252BPageletTestSkin%2Fcontainer%2F%2540%2540default.html'
-  >>> print browser.contents
-  <!DOCTYPE ...>
-  <html ...>
-  <head>
-  <title>PageletTestLayout</title>
-  </head>
-  <body>
-    <div>
-    <p>
-      Please provide Login Information
-    </p>
-    <form action="" method="post">
-      <div class="row">
-        <div class="label"><label for="login">User Name</label></div>
-        <div class="field">
-          <input type="text" name="login" id="login" />
-        </div>
-      </div>
-      <div class="row">
-        <div class="label"><label for="password">Password</label></div>
-        <div class="field">
-          <input type="password" name="password" id="password" />
-        </div>
-      </div>
-      <div class="row">
-        <input class="form-element" type="submit"
-               name="SUBMIT" value="Log in" />
-      </div>
-      <input type="hidden" name="camefrom"
-             value="/++skin++PageletTestSkin/container/@@login.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html">
-    </form>
-  </div>
-  </body>
-  </html>
-
-Entering wrong username does not authorize but display an error
-message:
-
-  >>> browser.getControl('User Name').value = 'me'
-  >>> browser.getControl('Password').value = 'tpass'
-  >>> browser.getControl('Log in').click()
-  >>> browser.url
-  'http://localhost/++skin++PageletTestSkin/@@loginForm.html?camefrom=%2F%2B%2Bskin%2B%2BPageletTestSkin%2Fcontainer%2F%40%40login.html%3FnextURL%3Dhttp%253A%2F%2Flocalhost%2F%252B%252Bskin%252B%252BPageletTestSkin%2Fcontainer%2F%2540%2540default.html'
-  >>> print browser.contents
-  <!DOCTYPE ...>
-  <html ...>
-  <head>
-  <title>PageletTestLayout</title>
-  </head>
-  <body>
-    <div>
-    <p>
-      Please provide Login Information
-    </p>
-    <form action="" method="post">
-      <div class="row">
-        <div class="label"><label for="login">User Name</label></div>
-        <div class="field">
-          <input type="text" name="login" id="login" />
-        </div>
-      </div>
-      <div class="row">
-        <div class="label"><label for="password">Password</label></div>
-        <div class="field">
-          <input type="password" name="password" id="password" />
-        </div>
-      </div>
-      <div class="row">
-        <input class="form-element" type="submit"
-               name="SUBMIT" value="Log in" />
-      </div>
-      <input type="hidden" name="camefrom"
-             value="/++skin++PageletTestSkin/container/@@login.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html">
-    </form>
-  </div>
-  </body>
-  </html>
-
-Entering wrong password does not authorize either:
-
-  >>> browser.getControl('User Name').value = 'tester'
-  >>> browser.getControl('Password').value = 'let me in'
-  >>> browser.getControl('Log in').click()
-  >>> browser.url
-  'http://localhost/++skin++PageletTestSkin/@@loginForm.html?camefrom=%2F%2B%2Bskin%2B%2BPageletTestSkin%2Fcontainer%2F%40%40login.html%3FnextURL%3Dhttp%253A%2F%2Flocalhost%2F%252B%252Bskin%252B%252BPageletTestSkin%2Fcontainer%2F%2540%2540default.html'
-  >>> print browser.contents
-  <!DOCTYPE ...>
-  <html ...>
-  <head>
-  <title>PageletTestLayout</title>
-  </head>
-  <body>
-    <div>
-    <p>
-      Please provide Login Information
-    </p>
-    <form action="" method="post">
-      <div class="row">
-        <div class="label"><label for="login">User Name</label></div>
-        <div class="field">
-          <input type="text" name="login" id="login" />
-        </div>
-      </div>
-      <div class="row">
-        <div class="label"><label for="password">Password</label></div>
-        <div class="field">
-          <input type="password" name="password" id="password" />
-        </div>
-      </div>
-      <div class="row">
-        <input class="form-element" type="submit"
-               name="SUBMIT" value="Log in" />
-      </div>
-      <input type="hidden" name="camefrom"
-             value="/++skin++PageletTestSkin/container/@@login.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html">
-    </form>
-  </div>
-  </body>
-  </html>
-
-
-After entering a correct username and password the user gets
-authorized:
-
-  >>> browser.getControl('User Name').value = 'tester'
-  >>> browser.getControl('Password').value = 'tpass'
-  >>> browser.getControl('Log in').click()
-
-The user gets redirected to the page where he selected the login
-link. After logging in the login link is no longer displayed. As we
-already specified that logout is supported, a logout link is
-displayed:
-
-  >>> browser.url
-  'http://localhost/++skin++PageletTestSkin/container/@@default.html'
-  >>> print browser.contents
-  <!DOCTYPE ...>
-  <html ...>
-    <head>
-      <title>PageletTest</title>
-    </head>
-    <body>
-      <a href="http://localhost/++skin++PageletTestSkin/container/@@logout.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html">Logout</a>
-    </body>
-  </html>
-
-
-Calling the login URL again leads directly to the page referred in nextURL:
-
-  >>> browser.open(login_url)
-  >>> browser.url
-  'http://localhost/++skin++PageletTestSkin/container/@@default.html'
-  >>> print browser.contents
-  <!DOCTYPE ...>
-  <html ...>
-    <head>
-      <title>PageletTest</title>
-    </head>
-    <body>
-      <a href="http://localhost/++skin++PageletTestSkin/container/@@logout.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html">Logout</a>
-    </body>
-  </html>
-
-Calling the login URL again without the query parameter leeds to a
-confirmation page telling that login was successfull:
-
-  >>> browser.open(login_url.split('?')[0])
-  >>> browser.url
-  'http://localhost/++skin++PageletTestSkin/container/@@login.html'
-  >>> print browser.contents
-  <!DOCTYPE ...>
-  <html ...>
-  <head>
-  <title>PageletTestLayout</title>
-  </head>
-  <body>
-    <div>
-     <h1>Login successful!</h1>
-     <p style="font-size: 200%"> You are now logged in as <em>Tester</em>. </p>
-     <a href=".">Back to the main page.</a>
-    </div>
-  </body>
-  </html>
-
-Selecting the ``Back to the main page.`` link send the user back to
-the default view of the container. (``ftesting.zcml`` defines
-``@@default.html`` as the default view.):
-
-  >>> browser.getLink('Back to the main page.').click()
-  >>> browser.url
-  'http://localhost/++skin++PageletTestSkin/container/'
-  >>> print browser.contents
-  <!DOCTYPE ...>
-  <html ...>
-    <head>
-      <title>PageletTest</title>
-    </head>
-    <body>
-      <a href="http://localhost/++skin++PageletTestSkin/container/@@logout.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html">Logout</a>
-    </body>
-  </html>
-
-
-Selecting the displayed logout link drops authentication information
-and displays a confirmation page, which redirects to the default page
-where the login link is displayed again (as redirection is done
-automatically by testbrowser I have to use the non API call trick
-again to show the displayed page):
-
-  >>> browser.mech_browser.set_handle_refresh(False)
-  >>> logout_url = browser.getLink('Logout').url
-  >>> browser.getLink('Logout').click()
-  >>> print browser.contents
-  <!DOCTYPE ...>
-  <html ...>
-    <head>
-      <title>PageletTest</title>
-      <script type="text/javascript"><!--
-    // clear HTTP Authentication
-    ...
-    //-->
-  </script>
-  <meta http-equiv="refresh"
-        content="0;url=http://localhost/++skin++PageletTestSkin/container/@@default.html" />
-    </head>
-    <body>
-      <a href="http://localhost/++skin++PageletTestSkin/container/@@logout.html/@@logout.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40logout.html">Logout</a>
-      <div>
-    <h1>You are being redirected!</h1>
-  <BLANKLINE>
-    <p style="font-size: 150%">
-      <a href="http://localhost/++skin++PageletTestSkin/container/@@default.html">
-        If you see this screen for more than 5 seconds, click here.
-      </a>
-    </p>
-  </div>
-    </body>
-  </html>
-  >>> browser.getLink('If you see this screen for more than 5 seconds').click()
-  >>> print browser.contents
-  <!DOCTYPE ...>
-  <html ...>
-    <head>
-      <title>PageletTest</title>
-    </head>
-    <body>
-      <a href="http://localhost/++skin++PageletTestSkin/container/@@login.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html">Login</a>
-    </body>
-  </html>
-  >>> browser.mech_browser.set_handle_refresh(True)
-
-Calling the logout URL again after logout leads directly to the page
-referred in nextURL:
-
-  >>> browser.open(logout_url)
-  >>> browser.url
-  'http://localhost/++skin++PageletTestSkin/container/@@default.html'
-  >>> print browser.contents
-  <!DOCTYPE ...>
-  <html ...>
-    <head>
-      <title>PageletTest</title>
-    </head>
-    <body>
-      <a href="http://localhost/++skin++PageletTestSkin/container/@@login.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html">Login</a>
-    </body>
-  </html>
-
-Calling the logout URL again without the query parameter leeds to a
-confirmation page telling that logout was successfull:
-
-  >>> browser.open(logout_url.split('?')[0])
-  >>> browser.url
-  'http://localhost/++skin++PageletTestSkin/container/@@logout.html'
-  >>> print browser.contents
-  <!DOCTYPE ...>
-  <html ...>
-    <head>
-      <title>PageletTest</title>
-      <script type="text/javascript"><!--
-    // clear HTTP Authentication
-    ...
-    //-->
-  </script>
-    </head>
-    <body>
-      <a href="http://localhost/++skin++PageletTestSkin/container/logout.html/@@login.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40logout.html">Login</a>
-      <div>
-    <h1>Logout successful!</h1>
-    <p style="font-size: 200%">
-      You are now logged out.
-    </p>
-    <a href=".">Back to the main page.</a>
-  </div>
-    </body>
-  </html>
+Login and logout
+----------------
+
+Login and logout work both for basic auth and cookie auth.
+
+
+Setup
+~~~~~
+
+The layout page template has to include two content providers (viewlet
+mangers):
+
+  - ``login-logout-head`` inside the head tag to get automatic
+    redirects and JavaScript code which does the logout for basic
+    auth and
+
+  - ``login-logout`` inside the body tag to get login and logout links.
+
+The sample template looks like this:
+
+  >>> import os.path
+  >>> template_path = os.path.join(os.path.dirname(__file__), "tests",
+  ...     "login-logout-template.pt")
+  >>> print file(template_path, "r").read()
+  <!DOCTYPE ...>
+  <html ...>
+    <head>
+      <title>PageletTest</title>
+      <tal:block replace="structure provider:login-logout-head" />
+    </head>
+    <body>
+      <tal:block replace="structure provider:login-logout" />
+      <tal:block replace="structure provider:pagelet" />
+    </body>
+  </html>
+
+This template is registered for the ``IContainer`` interface in
+``ftesting.zcml``. After creating a container the template is
+used when browsing the container:
+
+  >>> from zope.container.btree import BTreeContainer
+  >>> getRootFolder()['container'] = BTreeContainer()
+
+Basic auth
+~~~~~~~~~~
+
+When the user is not logged in the login link is displayed:
+
+  >>> from zope.testbrowser.testing import Browser
+  >>> skinURL = 'http://localhost/++skin++PageletTestSkin/'
+  >>> browser = Browser()
+  >>> browser.handleErrors = False
+  >>> browser.open(skinURL + 'container/@@default.html')
+  >>> browser.url
+  'http://localhost/++skin++PageletTestSkin/container/@@default.html'
+  >>> print browser.contents
+  <!DOCTYPE ...>
+  <html ...>
+    <head>
+      <title>PageletTest</title>
+    </head>
+    <body>
+      <a href="http://localhost/++skin++PageletTestSkin/container/@@login.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html">Login</a>
+    </body>
+  </html>
+
+Selecting the link leads to the login page, as we use basic auth here,
+we get an HTTP error 401 (unauthorized):
+
+  >>> login_url = browser.getLink('Login').url
+  >>> browser.getLink('Login').click()
+  Traceback (most recent call last):
+  httperror_seek_wrapper: HTTP Error 401: Unauthorized
+  >>> browser.url
+  'http://localhost/++skin++PageletTestSkin/container/@@login.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html'
+
+When adding correct credentials we get authorized:
+
+  >>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+  >>> browser.reload()
+
+We are redirected to the page where we selected the login link. After
+logging in the login link is no longer displayed. As we did not
+specify that logout is supported, no logout link is displayed:
+
+  >>> browser.url
+  'http://localhost/++skin++PageletTestSkin/container/@@default.html'
+  >>> print browser.contents
+  <!DOCTYPE ...>
+  <html ...>
+    <head>
+      <title>PageletTest</title>
+    </head>
+    <body>
+    </body>
+  </html>
+
+Calling the login URL again leads directly to the page referred in nextURL:
+
+  >>> browser.open(login_url)
+  >>> browser.url
+  'http://localhost/++skin++PageletTestSkin/container/@@default.html'
+  >>> print browser.contents
+  <!DOCTYPE ...>
+  <html ...>
+    <head>
+      <title>PageletTest</title>
+    </head>
+    <body>
+    </body>
+  </html>
+
+Calling the login URL again without the query parameter leeds to a
+confirmation page telling that login was successfull:
+
+  >>> browser.open(login_url.split('?')[0])
+  >>> browser.url
+  'http://localhost/++skin++PageletTestSkin/container/@@login.html'
+  >>> print browser.contents
+  <!DOCTYPE ...>
+  <html ...>
+  <head>
+  <title>PageletTestLayout</title>
+  </head>
+  <body>
+    <div>
+     <h1>Login successful!</h1>
+     <p style="font-size: 200%"> You are now logged in as <em>Manager</em>. </p>
+     <a href=".">Back to the main page.</a>
+    </div>
+  </body>
+  </html>
+
+Selecting the ``Back to the main page.`` link send the user back to
+the default view of the container. (``ftesting.zcml`` defines
+``@@default.html`` as the default view.):
+
+  >>> browser.getLink('Back to the main page.').click()
+  >>> browser.url
+  'http://localhost/++skin++PageletTestSkin/container/'
+  >>> print browser.contents
+  <!DOCTYPE ...>
+  <html ...>
+    <head>
+      <title>PageletTest</title>
+    </head>
+    <body>
+    </body>
+  </html>
+
+
+Providing an ``ILogoutSupported`` adapter leads to a logout link being
+displayed:
+
+  >>> from zope.app.testing import ztapi
+  >>> import zope.interface
+  >>> import zope.authentication.logout
+  >>> import zope.authentication.interfaces
+  >>> ztapi.provideAdapter(
+  ...     zope.interface.Interface,
+  ...     zope.authentication.interfaces.ILogoutSupported,
+  ...     zope.authentication.logout.LogoutSupported)
+  >>> browser.reload()
+  >>> browser.url
+  'http://localhost/++skin++PageletTestSkin/container/'
+  >>> print browser.contents
+  <!DOCTYPE ...>
+  <html ...>
+    <head>
+      <title>PageletTest</title>
+    </head>
+    <body>
+      <a href="http://localhost/++skin++PageletTestSkin/container/@@logout.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html">Logout</a>
+    </body>
+  </html>
+
+Logout is done using JavaScript and a redirect. zope.testbrowser
+follows the redirects even if they use the meta tag instead of the
+status code. So I have to use a non API call to change this behavior
+to show the file contents:
+
+  >>> browser.mech_browser.set_handle_refresh(False)
+
+As testbrowser is not able to execute JavaScript the user remains
+authenticated:
+
+  >>> logout_url = browser.getLink('Logout').url
+  >>> browser.getLink('Logout').click()
+  >>> browser.url
+  'http://localhost/++skin++PageletTestSkin/container/@@logout.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html'
+  >>> print browser.contents
+  <!DOCTYPE ...>
+  <html ...>
+    <head>
+      <title>PageletTest</title>
+      <script type="text/javascript"><!--
+    // clear HTTP Authentication
+    ...
+    //-->
+  </script>
+  <meta http-equiv="refresh"
+        content="0;url=http://localhost/++skin++PageletTestSkin/container/@@default.html" />
+    </head>
+    <body>
+      <a href="http://localhost/++skin++PageletTestSkin/container/@@logout.html/@@logout.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40logout.html">Logout</a>
+      <div>
+    <h1>You are being redirected!</h1>
+    <p style="font-size: 150%">
+      <a href="http://localhost/++skin++PageletTestSkin/container/@@default.html">
+        If you see this screen for more than 5 seconds, click here.
+      </a>
+    </p>
+  </div>
+    </body>
+  </html>
+
+Calling the logout URL again after logout (simulated using a new
+browser instance) leads directly to the page referred in nextURL:
+
+  >>> browser2 = Browser(logout_url)
+  >>> browser2.url
+  'http://localhost/++skin++PageletTestSkin/container/@@default.html'
+  >>> print browser2.contents
+  <!DOCTYPE ...>
+  <html ...>
+    <head>
+      <title>PageletTest</title>
+    </head>
+    <body>
+      <a href="http://localhost/++skin++PageletTestSkin/container/@@login.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html">Login</a>
+    </body>
+  </html>
+
+Calling the logout URL again without the query parameter leeds to a
+confirmation page telling that logout was successfull:
+
+  >>> browser2.open(logout_url.split('?')[0])
+  >>> browser2.url
+  'http://localhost/++skin++PageletTestSkin/container/@@logout.html'
+  >>> print browser2.contents
+  <!DOCTYPE ...>
+  <html ...>
+    <head>
+      <title>PageletTest</title>
+      <script type="text/javascript"><!--
+    // clear HTTP Authentication
+    ...
+    //-->
+  </script>
+    </head>
+    <body>
+      <a href="http://localhost/++skin++PageletTestSkin/container/logout.html/@@login.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40logout.html">Login</a>
+      <div>
+    <h1>Logout successful!</h1>
+    <p style="font-size: 200%">
+      You are now logged out.
+    </p>
+    <a href=".">Back to the main page.</a>
+  </div>
+    </body>
+  </html>
+
+
+Cookie auth
+~~~~~~~~~~~
+
+To do cookie auth we have to set up a pluggable auth utility (PAU)
+with a authenticator plug-in (principal folder) first:
+
+  >>> from zope.authentication.interfaces import IAuthentication
+  >>> from zope.app.authentication.interfaces import IAuthenticatorPlugin
+  >>> from zope.app.authentication.authentication import PluggableAuthentication
+  >>> from zope.app.authentication.principalfolder import PrincipalFolder
+  >>> from zope.site import site
+
+  >>> root = getRootFolder()
+  >>> root['principal_folder'] = PrincipalFolder()
+  >>> sm = root.getSiteManager()
+  >>> sm.registerUtility(
+  ...     root['principal_folder'], IAuthenticatorPlugin, 'principal_folder')
+
+  >>> root['auth'] = PluggableAuthentication()
+  >>> sm.registerUtility(root['auth'], IAuthentication, '')
+  >>> root['auth'].credentialsPlugins = (u'Session Credentials',)
+  >>> root['auth'].authenticatorPlugins = (u'principal_folder',)
+
+We need a principal inside the principal folder:
+
+  >>> from zope.app.authentication.principalfolder import InternalPrincipal
+  >>> root['principal_folder']['1'] = InternalPrincipal(
+  ...     'tester', 'tpass', 'Tester')
+
+
+We use a new browser, so the principal is not logged in and the login
+link is displayed:
+
+  >>> browser = Browser()
+  >>> browser.open(skinURL + 'container/@@default.html')
+  >>> browser.url
+  'http://localhost/++skin++PageletTestSkin/container/@@default.html'
+  >>> print browser.contents
+  <!DOCTYPE ...>
+  <html ...>
+    <head>
+      <title>PageletTest</title>
+    </head>
+    <body>
+      <a href="http://localhost/++skin++PageletTestSkin/container/@@login.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html">Login</a>
+    </body>
+  </html>
+
+Selecting the link leads to the login page:
+
+  >>> login_url = browser.getLink('Login').url
+  >>> browser.getLink('Login').click()
+  >>> browser.url
+  'http://localhost/++skin++PageletTestSkin/@@loginForm.html?camefrom=%2F%2B%2Bskin%2B%2BPageletTestSkin%2Fcontainer%2F%40%40login.html%3FnextURL%3Dhttp%253A%2F%2Flocalhost%2F%252B%252Bskin%252B%252BPageletTestSkin%2Fcontainer%2F%2540%2540default.html'
+  >>> print browser.contents
+  <!DOCTYPE ...>
+  <html ...>
+  <head>
+  <title>PageletTestLayout</title>
+  </head>
+  <body>
+    <div>
+    <p>
+      Please provide Login Information
+    </p>
+    <form action="" method="post">
+      <div class="row">
+        <div class="label"><label for="login">User Name</label></div>
+        <div class="field">
+          <input type="text" name="login" id="login" />
+        </div>
+      </div>
+      <div class="row">
+        <div class="label"><label for="password">Password</label></div>
+        <div class="field">
+          <input type="password" name="password" id="password" />
+        </div>
+      </div>
+      <div class="row">
+        <input class="form-element" type="submit"
+               name="SUBMIT" value="Log in" />
+      </div>
+      <input type="hidden" name="camefrom"
+             value="/++skin++PageletTestSkin/container/@@login.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html">
+    </form>
+  </div>
+  </body>
+  </html>
+
+Entering wrong username does not authorize but display an error
+message:
+
+  >>> browser.getControl('User Name').value = 'me'
+  >>> browser.getControl('Password').value = 'tpass'
+  >>> browser.getControl('Log in').click()
+  >>> browser.url
+  'http://localhost/++skin++PageletTestSkin/@@loginForm.html?camefrom=%2F%2B%2Bskin%2B%2BPageletTestSkin%2Fcontainer%2F%40%40login.html%3FnextURL%3Dhttp%253A%2F%2Flocalhost%2F%252B%252Bskin%252B%252BPageletTestSkin%2Fcontainer%2F%2540%2540default.html'
+  >>> print browser.contents
+  <!DOCTYPE ...>
+  <html ...>
+  <head>
+  <title>PageletTestLayout</title>
+  </head>
+  <body>
+    <div>
+    <p>
+      Please provide Login Information
+    </p>
+    <form action="" method="post">
+      <div class="row">
+        <div class="label"><label for="login">User Name</label></div>
+        <div class="field">
+          <input type="text" name="login" id="login" />
+        </div>
+      </div>
+      <div class="row">
+        <div class="label"><label for="password">Password</label></div>
+        <div class="field">
+          <input type="password" name="password" id="password" />
+        </div>
+      </div>
+      <div class="row">
+        <input class="form-element" type="submit"
+               name="SUBMIT" value="Log in" />
+      </div>
+      <input type="hidden" name="camefrom"
+             value="/++skin++PageletTestSkin/container/@@login.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html">
+    </form>
+  </div>
+  </body>
+  </html>
+
+Entering wrong password does not authorize either:
+
+  >>> browser.getControl('User Name').value = 'tester'
+  >>> browser.getControl('Password').value = 'let me in'
+  >>> browser.getControl('Log in').click()
+  >>> browser.url
+  'http://localhost/++skin++PageletTestSkin/@@loginForm.html?camefrom=%2F%2B%2Bskin%2B%2BPageletTestSkin%2Fcontainer%2F%40%40login.html%3FnextURL%3Dhttp%253A%2F%2Flocalhost%2F%252B%252Bskin%252B%252BPageletTestSkin%2Fcontainer%2F%2540%2540default.html'
+  >>> print browser.contents
+  <!DOCTYPE ...>
+  <html ...>
+  <head>
+  <title>PageletTestLayout</title>
+  </head>
+  <body>
+    <div>
+    <p>
+      Please provide Login Information
+    </p>
+    <form action="" method="post">
+      <div class="row">
+        <div class="label"><label for="login">User Name</label></div>
+        <div class="field">
+          <input type="text" name="login" id="login" />
+        </div>
+      </div>
+      <div class="row">
+        <div class="label"><label for="password">Password</label></div>
+        <div class="field">
+          <input type="password" name="password" id="password" />
+        </div>
+      </div>
+      <div class="row">
+        <input class="form-element" type="submit"
+               name="SUBMIT" value="Log in" />
+      </div>
+      <input type="hidden" name="camefrom"
+             value="/++skin++PageletTestSkin/container/@@login.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html">
+    </form>
+  </div>
+  </body>
+  </html>
+
+
+After entering a correct username and password the user gets
+authorized:
+
+  >>> browser.getControl('User Name').value = 'tester'
+  >>> browser.getControl('Password').value = 'tpass'
+  >>> browser.getControl('Log in').click()
+
+The user gets redirected to the page where he selected the login
+link. After logging in the login link is no longer displayed. As we
+already specified that logout is supported, a logout link is
+displayed:
+
+  >>> browser.url
+  'http://localhost/++skin++PageletTestSkin/container/@@default.html'
+  >>> print browser.contents
+  <!DOCTYPE ...>
+  <html ...>
+    <head>
+      <title>PageletTest</title>
+    </head>
+    <body>
+      <a href="http://localhost/++skin++PageletTestSkin/container/@@logout.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html">Logout</a>
+    </body>
+  </html>
+
+
+Calling the login URL again leads directly to the page referred in nextURL:
+
+  >>> browser.open(login_url)
+  >>> browser.url
+  'http://localhost/++skin++PageletTestSkin/container/@@default.html'
+  >>> print browser.contents
+  <!DOCTYPE ...>
+  <html ...>
+    <head>
+      <title>PageletTest</title>
+    </head>
+    <body>
+      <a href="http://localhost/++skin++PageletTestSkin/container/@@logout.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html">Logout</a>
+    </body>
+  </html>
+
+Calling the login URL again without the query parameter leeds to a
+confirmation page telling that login was successfull:
+
+  >>> browser.open(login_url.split('?')[0])
+  >>> browser.url
+  'http://localhost/++skin++PageletTestSkin/container/@@login.html'
+  >>> print browser.contents
+  <!DOCTYPE ...>
+  <html ...>
+  <head>
+  <title>PageletTestLayout</title>
+  </head>
+  <body>
+    <div>
+     <h1>Login successful!</h1>
+     <p style="font-size: 200%"> You are now logged in as <em>Tester</em>. </p>
+     <a href=".">Back to the main page.</a>
+    </div>
+  </body>
+  </html>
+
+Selecting the ``Back to the main page.`` link send the user back to
+the default view of the container. (``ftesting.zcml`` defines
+``@@default.html`` as the default view.):
+
+  >>> browser.getLink('Back to the main page.').click()
+  >>> browser.url
+  'http://localhost/++skin++PageletTestSkin/container/'
+  >>> print browser.contents
+  <!DOCTYPE ...>
+  <html ...>
+    <head>
+      <title>PageletTest</title>
+    </head>
+    <body>
+      <a href="http://localhost/++skin++PageletTestSkin/container/@@logout.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html">Logout</a>
+    </body>
+  </html>
+
+
+Selecting the displayed logout link drops authentication information
+and displays a confirmation page, which redirects to the default page
+where the login link is displayed again (as redirection is done
+automatically by testbrowser I have to use the non API call trick
+again to show the displayed page):
+
+  >>> browser.mech_browser.set_handle_refresh(False)
+  >>> logout_url = browser.getLink('Logout').url
+  >>> browser.getLink('Logout').click()
+  >>> print browser.contents
+  <!DOCTYPE ...>
+  <html ...>
+    <head>
+      <title>PageletTest</title>
+      <script type="text/javascript"><!--
+    // clear HTTP Authentication
+    ...
+    //-->
+  </script>
+  <meta http-equiv="refresh"
+        content="0;url=http://localhost/++skin++PageletTestSkin/container/@@default.html" />
+    </head>
+    <body>
+      <a href="http://localhost/++skin++PageletTestSkin/container/@@logout.html/@@logout.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40logout.html">Logout</a>
+      <div>
+    <h1>You are being redirected!</h1>
+  <BLANKLINE>
+    <p style="font-size: 150%">
+      <a href="http://localhost/++skin++PageletTestSkin/container/@@default.html">
+        If you see this screen for more than 5 seconds, click here.
+      </a>
+    </p>
+  </div>
+    </body>
+  </html>
+  >>> browser.getLink('If you see this screen for more than 5 seconds').click()
+  >>> print browser.contents
+  <!DOCTYPE ...>
+  <html ...>
+    <head>
+      <title>PageletTest</title>
+    </head>
+    <body>
+      <a href="http://localhost/++skin++PageletTestSkin/container/@@login.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html">Login</a>
+    </body>
+  </html>
+  >>> browser.mech_browser.set_handle_refresh(True)
+
+Calling the logout URL again after logout leads directly to the page
+referred in nextURL:
+
+  >>> browser.open(logout_url)
+  >>> browser.url
+  'http://localhost/++skin++PageletTestSkin/container/@@default.html'
+  >>> print browser.contents
+  <!DOCTYPE ...>
+  <html ...>
+    <head>
+      <title>PageletTest</title>
+    </head>
+    <body>
+      <a href="http://localhost/++skin++PageletTestSkin/container/@@login.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html">Login</a>
+    </body>
+  </html>
+
+Calling the logout URL again without the query parameter leeds to a
+confirmation page telling that logout was successfull:
+
+  >>> browser.open(logout_url.split('?')[0])
+  >>> browser.url
+  'http://localhost/++skin++PageletTestSkin/container/@@logout.html'
+  >>> print browser.contents
+  <!DOCTYPE ...>
+  <html ...>
+    <head>
+      <title>PageletTest</title>
+      <script type="text/javascript"><!--
+    // clear HTTP Authentication
+    ...
+    //-->
+  </script>
+    </head>
+    <body>
+      <a href="http://localhost/++skin++PageletTestSkin/container/logout.html/@@login.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40logout.html">Login</a>
+      <div>
+    <h1>Logout successful!</h1>
+    <p style="font-size: 200%">
+      You are now logged out.
+    </p>
+    <a href=".">Back to the main page.</a>
+  </div>
+    </body>
+  </html>

Modified: z3c.authviewlet/trunk/src/z3c/authviewlet/tests/ftesting.zcml
===================================================================
--- z3c.authviewlet/trunk/src/z3c/authviewlet/tests/ftesting.zcml	2010-10-13 13:31:03 UTC (rev 117513)
+++ z3c.authviewlet/trunk/src/z3c/authviewlet/tests/ftesting.zcml	2010-10-13 13:41:25 UTC (rev 117514)
@@ -8,6 +8,18 @@
   <!-- re-use ftesting configuration -->
   <include package="z3c.layer.pagelet.tests" file="ftesting.zcml" />
 
+  <!-- exclude will prevent from include -->
+  <exclude package="zope.app.authentication" file="ftpplugins.zcml" />
+  <exclude package="zope.app.authentication" file="groupfolder.zcml" />
+  <exclude package="zope.app.authentication.browser" />
+  <exclude package="zope.app.authentication.browser" file="configure.zcml" />
+  <exclude package="zope.app.authentication.browser" file="groupfolder.zcml" />
+  <exclude package="zope.app.authentication.browser" file="httpplugins.zcml" />
+  <exclude package="zope.app.authentication.browser" file="principalfolder.zcml" />
+  <exclude package="zope.app.authentication.browser" file="session.zcml" />
+
+  <include package="zope.app.authentication" />
+
   <!-- load additional configuration -->
   <include package="zope.viewlet" file="meta.zcml" />
   <include package="zope.viewlet" />
@@ -51,4 +63,8 @@
       template="login-logout-template.pt"
       />
 
+  <!-- -->
+
+  <grantAll role="zope.Anonymous" />
+
 </configure>



More information about the checkins mailing list