Skip to main content
Archived

This project has been archived by its maintainers, and is no longer receiving any updates.

This package provides an authentication viewlet implementation for Zope3.

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")
>>> with open(template_path, "r") as t:
...     print(t.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
>>> layer.getRootFolder()['container'] = BTreeContainer()

Basic auth

When the user is not logged in the login link is displayed:

>>> from zope.testbrowser.wsgi import Browser
>>> skinURL = 'http://localhost/++skin++PageletTestSkin/'
>>> wsgi_app = layer.make_wsgi_app()
>>> browser = Browser(wsgi_app=wsgi_app)
>>> 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.raiseHttpErrors = False
>>> browser.getLink('Login').click()
>>> print(browser.headers['status'])
401 Unauthorized
>>> print(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.open(browser.url)

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:

>>> print(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)
>>> print(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])
>>> print(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()
>>> print(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:

>>> import zope.component
>>> import zope.interface
>>> import zope.authentication.logout
>>> import zope.authentication.interfaces
>>> zope.component.provideAdapter(
...     zope.authentication.logout.LogoutSupported,
...     adapts=[zope.interface.Interface],
...     provides=zope.authentication.interfaces.ILogoutSupported)
>>> browser.reload()
>>> print(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 >= 5.0 does not follow redirects if they use the meta tag.

As testbrowser is not able to execute JavaScript the user remains authenticated:

>>> logout_url = browser.getLink('Logout').url
>>> browser.getLink('Logout').click()
>>> print(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, wsgi_app=wsgi_app)
>>> print(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])
>>> print(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>

Changes

2.0 (2023-02-09)

  • Add support for Python 3.8, 3.9, 3.10, 3.11.

  • Drop support for Python 2.7, 3.4, 3.5, 3.6.

1.1 (2018-10-18)

  • Add support for Python 3.7.

1.0.1 (2017-06-08)

  • Fix dependencies declared in setup.py.

1.0 (2017-06-07)

  • Update to Python 3. Now supporting: Python 3.4 to 3.6, PyPy2 and PyPy3.

  • Update the tests to zope.testbrowser >= 5.0.

0.8.0 (2010-10-13)

  • Adapted test set up to the changes in z3c.layer.pagelet 1.9 thus requiring at least this version now.

  • Moved code from page template of session credentials login page to view class so it can be customized. (Taken from zope.app.authentication.browser.loginform.LoginForm.) Moved view class SessionCredentialsLoginForm from z3c.authviewlet.auth to z3c.authviewlet.session.

0.7.0 (2009-12-27)

  • Moved files in z3c.authviewlet.browser to z3c.authviewlet as we only have browser code in this package.

  • Broke dependency on zope.app.publisher by defining our own ILogin interface.

0.6.0 (2009-12-24)

  • Added i18n domains to allow translation (done in z3c.locales package).

0.5.0 (2009-11-30)

  • Moved authentication viewlet implementation from z3c.layer.pagelet to this package.

  • Initial release.

Release files for z3c.authviewlet 2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for z3c.authviewlet 2.0
File Size Uploaded
z3c.authviewlet-2.0.tar.gz 19.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for z3c.authviewlet 2.0
File Interpreter ABI Platform
z3c.authviewlet-2.0-py3-none-any.whl Python 3 none any Details

Total release size: 39.6 kB

Release files / z3c.authviewlet-2.0.tar.gz

Download URL z3c.authviewlet-2.0.tar.gz
Size 19.6 kB
Tags Source
SHA-256 checksum
How to use checksums
e502d2e45956339400e4402325bad8d768e146680ea2f5e4449709cf8d589dd4
BLAKE2b-256 checksum
How to use checksums
1d1db08d45b6fba8b645931d364d964d9adf7968f68ed0d473748bc3b7bca6b6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.16

Release files / z3c.authviewlet-2.0-py3-none-any.whl

Download URL z3c.authviewlet-2.0-py3-none-any.whl
Size 20.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f833cd503bbc8aa0bc39a0a1cb830964c039cf9c3ad67659ce64843e91b6866a
BLAKE2b-256 checksum
How to use checksums
533a1afaed5467746d685fc91e8aa0a94c1f6676d8cd50cebe0fa3c08d0b32df
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.16
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page