Skip to main content

Authentication viewlet for Zope3

Project description

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

z3c.authviewlet-2.0.tar.gz (19.6 kB view details)

Uploaded Source

Built Distribution

z3c.authviewlet-2.0-py3-none-any.whl (20.0 kB view details)

Uploaded Python 3

File details

Details for the file z3c.authviewlet-2.0.tar.gz.

File metadata

  • Download URL: z3c.authviewlet-2.0.tar.gz
  • Upload date:
  • Size: 19.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.16

File hashes

Hashes for z3c.authviewlet-2.0.tar.gz
Algorithm Hash digest
SHA256 e502d2e45956339400e4402325bad8d768e146680ea2f5e4449709cf8d589dd4
MD5 14ef6fdbf25c79be59d16232090f03a9
BLAKE2b-256 1d1db08d45b6fba8b645931d364d964d9adf7968f68ed0d473748bc3b7bca6b6

See more details on using hashes here.

File details

Details for the file z3c.authviewlet-2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for z3c.authviewlet-2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f833cd503bbc8aa0bc39a0a1cb830964c039cf9c3ad67659ce64843e91b6866a
MD5 af73512f97d033607fe225765f29fbe3
BLAKE2b-256 533a1afaed5467746d685fc91e8aa0a94c1f6676d8cd50cebe0fa3c08d0b32df

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page