{ "info": { "author": "Zope Foundation and Contributors", "author_email": "zope-dev@zope.org", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Framework :: Zope :: 3", "Intended Audience :: Developers", "License :: OSI Approved :: Zope Public License", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Internet :: WWW/HTTP" ], "description": "This package provides an authentication viewlet implementation for Zope3.\n\n\n.. contents::\n\nLogin and logout\n----------------\n\nLogin and logout work both for basic auth and cookie auth.\n\n\nSetup\n~~~~~\n\nThe layout page template has to include two content providers (viewlet\nmangers):\n\n - ``login-logout-head`` inside the head tag to get automatic\n redirects and JavaScript code which does the logout for basic\n auth and\n\n - ``login-logout`` inside the body tag to get login and logout links.\n\nThe sample template looks like this:\n\n >>> import os.path\n >>> template_path = os.path.join(os.path.dirname(__file__), \"tests\",\n ... \"login-logout-template.pt\")\n >>> with open(template_path, \"r\") as t:\n ... print(t.read())\n \n \n \n PageletTest\n \n \n \n \n \n \n \n\nThis template is registered for the ``IContainer`` interface in\n``ftesting.zcml``. After creating a container the template is\nused when browsing the container:\n\n >>> from zope.container.btree import BTreeContainer\n >>> layer.getRootFolder()['container'] = BTreeContainer()\n\nBasic auth\n~~~~~~~~~~\n\nWhen the user is not logged in the login link is displayed:\n\n >>> from zope.testbrowser.wsgi import Browser\n >>> skinURL = 'http://localhost/++skin++PageletTestSkin/'\n >>> wsgi_app = layer.make_wsgi_app()\n >>> browser = Browser(wsgi_app=wsgi_app)\n >>> browser.handleErrors = False\n >>> browser.open(skinURL + 'container/@@default.html')\n >>> browser.url\n 'http://localhost/++skin++PageletTestSkin/container/@@default.html'\n >>> print(browser.contents)\n \n \n \n PageletTest\n \n \n Login\n \n \n\nSelecting the link leads to the login page, as we use basic auth here,\nwe get an HTTP error 401 (unauthorized):\n\n >>> login_url = browser.getLink('Login').url\n >>> browser.getLink('Login').click()\n Traceback (most recent call last):\n httperror_seek_wrapper: HTTP Error 401: Unauthorized\n >>> print(browser.url)\n http://localhost/++skin++PageletTestSkin/container/@@login.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html\n\nWhen adding correct credentials we get authorized:\n\n >>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')\n >>> browser.open(browser.url)\n\nWe are redirected to the page where we selected the login link. After\nlogging in the login link is no longer displayed. As we did not\nspecify that logout is supported, no logout link is displayed:\n\n >>> print(browser.url)\n http://localhost/++skin++PageletTestSkin/container/@@default.html\n >>> print(browser.contents)\n \n \n \n PageletTest\n \n \n \n \n\nCalling the login URL again leads directly to the page referred in nextURL:\n\n >>> browser.open(login_url)\n >>> print(browser.url)\n http://localhost/++skin++PageletTestSkin/container/@@default.html\n >>> print(browser.contents)\n \n \n \n PageletTest\n \n \n \n \n\nCalling the login URL again without the query parameter leeds to a\nconfirmation page telling that login was successfull:\n\n >>> browser.open(login_url.split('?')[0])\n >>> print(browser.url)\n http://localhost/++skin++PageletTestSkin/container/@@login.html\n >>> print(browser.contents)\n \n \n \n PageletTestLayout\n \n \n
\n

Login successful!

\n

You are now logged in as Manager.

\n Back to the main page.\n
\n \n \n\nSelecting the ``Back to the main page.`` link send the user back to\nthe default view of the container. (``ftesting.zcml`` defines\n``@@default.html`` as the default view.):\n\n >>> browser.getLink('Back to the main page.').click()\n >>> print(browser.url)\n http://localhost/++skin++PageletTestSkin/container/\n >>> print(browser.contents)\n \n \n \n PageletTest\n \n \n \n \n\n\nProviding an ``ILogoutSupported`` adapter leads to a logout link being\ndisplayed:\n\n >>> import zope.component\n >>> import zope.interface\n >>> import zope.authentication.logout\n >>> import zope.authentication.interfaces\n >>> zope.component.provideAdapter(\n ... zope.authentication.logout.LogoutSupported,\n ... adapts=[zope.interface.Interface],\n ... provides=zope.authentication.interfaces.ILogoutSupported)\n >>> browser.reload()\n >>> print(browser.url)\n http://localhost/++skin++PageletTestSkin/container/\n >>> print(browser.contents)\n \n \n \n PageletTest\n \n \n Logout\n \n \n\nLogout is done using JavaScript and a redirect. zope.testbrowser >= 5.0\ndoes not follow redirects if they use the meta tag.\n\nAs testbrowser is not able to execute JavaScript the user remains\nauthenticated:\n\n >>> logout_url = browser.getLink('Logout').url\n >>> browser.getLink('Logout').click()\n >>> print(browser.url)\n http://localhost/++skin++PageletTestSkin/container/@@logout.html?nextURL=http%3A//localhost/%2B%2Bskin%2B%2BPageletTestSkin/container/%40%40default.html\n >>> print(browser.contents)\n \n \n \n PageletTest\n \n \n \n \n Logout\n
\n

You are being redirected!

\n

\n \n If you see this screen for more than 5 seconds, click here.\n \n

\n
\n \n \n\nCalling the logout URL again after logout (simulated using a new\nbrowser instance) leads directly to the page referred in nextURL:\n\n >>> browser2 = Browser(logout_url, wsgi_app=wsgi_app)\n >>> print(browser2.url)\n http://localhost/++skin++PageletTestSkin/container/@@default.html\n >>> print(browser2.contents)\n \n \n \n PageletTest\n \n \n Login\n \n \n\nCalling the logout URL again without the query parameter leeds to a\nconfirmation page telling that logout was successfull:\n\n >>> browser2.open(logout_url.split('?')[0])\n >>> print(browser2.url)\n http://localhost/++skin++PageletTestSkin/container/@@logout.html\n >>> print(browser2.contents)\n \n \n \n PageletTest\n \n \n \n Login\n
\n

Logout successful!

\n

\n You are now logged out.\n

\n Back to the main page.\n
\n \n \n\n\nCookie auth\n~~~~~~~~~~~\n\nTo do cookie auth we have to set up a pluggable auth utility (PAU)\nwith a authenticator plug-in (principal folder) first:\n\n >>> from zope.authentication.interfaces import IAuthentication\n >>> from zope.pluggableauth.interfaces import IAuthenticatorPlugin\n >>> from zope.pluggableauth.authentication import PluggableAuthentication\n >>> from zope.pluggableauth.plugins.principalfolder import PrincipalFolder\n >>> from zope.site import site\n\n >>> root = layer.getRootFolder()\n >>> root['principal_folder'] = PrincipalFolder()\n >>> sm = root.getSiteManager()\n >>> sm.registerUtility(\n ... root['principal_folder'], IAuthenticatorPlugin, 'principal_folder')\n\n >>> root['auth'] = PluggableAuthentication()\n >>> sm.registerUtility(root['auth'], IAuthentication, '')\n >>> root['auth'].credentialsPlugins = (u'Session Credentials',)\n >>> root['auth'].authenticatorPlugins = (u'principal_folder',)\n\nWe need a principal inside the principal folder:\n\n >>> from zope.pluggableauth.plugins.principalfolder import InternalPrincipal\n >>> root['principal_folder']['1'] = InternalPrincipal(\n ... 'tester', 'tpass', 'Tester')\n\n\nWe use a new browser, so the principal is not logged in and the login\nlink is displayed:\n\n >>> browser = Browser(wsgi_app=wsgi_app)\n >>> browser.open(skinURL + 'container/@@default.html')\n >>> print(browser.url)\n http://localhost/++skin++PageletTestSkin/container/@@default.html\n >>> print(browser.contents)\n \n \n \n PageletTest\n \n \n Login\n \n \n\nSelecting the link leads to the login page:\n\n >>> login_url = browser.getLink('Login').url\n >>> browser.getLink('Login').click()\n >>> print(browser.url)\n http://localhost/++skin++PageletTestSkin/@@loginForm.html?camefrom=http%3A%2F%2Flocalhost%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\n >>> print(browser.contents)\n \n \n \n PageletTestLayout\n \n \n
\n

\n Please provide Login Information\n

\n
\n
\n
\n
\n \n
\n
\n
\n
\n
\n \n
\n
\n
\n \n
\n \n
\n
\n \n \n\nEntering wrong username does not authorize but display an error\nmessage:\n\n >>> browser.getControl('User Name').value = 'me'\n >>> browser.getControl('Password').value = 'tpass'\n >>> browser.getControl('Log in').click()\n >>> print(browser.url)\n http://localhost/++skin++PageletTestSkin/@@loginForm.html?camefrom=http%3A%2F%2Flocalhost%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\n >>> print(browser.contents)\n \n \n \n PageletTestLayout\n \n \n
\n

\n Please provide Login Information\n

\n
\n
\n
\n
\n \n
\n
\n
\n
\n
\n \n
\n
\n
\n \n
\n \n
\n
\n \n \n\nEntering wrong password does not authorize either:\n\n >>> browser.getControl('User Name').value = 'tester'\n >>> browser.getControl('Password').value = 'let me in'\n >>> browser.getControl('Log in').click()\n >>> print(browser.url)\n http://localhost/++skin++PageletTestSkin/@@loginForm.html?camefrom=http%3A%2F%2Flocalhost%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\n >>> print(browser.contents)\n \n \n \n PageletTestLayout\n \n \n
\n

\n Please provide Login Information\n

\n
\n
\n
\n
\n \n
\n
\n
\n
\n
\n \n
\n
\n
\n \n
\n \n
\n
\n \n \n\n\nAfter entering a correct username and password the user gets\nauthorized:\n\n >>> browser.getControl('User Name').value = 'tester'\n >>> browser.getControl('Password').value = 'tpass'\n >>> browser.getControl('Log in').click()\n\nThe user gets redirected to the page where he selected the login\nlink. After logging in the login link is no longer displayed. As we\nalready specified that logout is supported, a logout link is\ndisplayed:\n\n >>> print(browser.url)\n http://localhost/++skin++PageletTestSkin/container/@@default.html\n >>> print(browser.contents)\n \n \n \n PageletTest\n \n \n Logout\n \n \n\n\nCalling the login URL again leads directly to the page referred in nextURL:\n\n >>> browser.open(login_url)\n >>> print(browser.url)\n http://localhost/++skin++PageletTestSkin/container/@@default.html\n >>> print(browser.contents)\n \n \n \n PageletTest\n \n \n Logout\n \n \n\nCalling the login URL again without the query parameter leeds to a\nconfirmation page telling that login was successfull:\n\n >>> browser.open(login_url.split('?')[0])\n >>> print(browser.url)\n http://localhost/++skin++PageletTestSkin/container/@@login.html\n >>> print(browser.contents)\n \n \n \n PageletTestLayout\n \n \n
\n

Login successful!

\n

You are now logged in as Tester.

\n Back to the main page.\n
\n \n \n\nSelecting the ``Back to the main page.`` link send the user back to\nthe default view of the container. (``ftesting.zcml`` defines\n``@@default.html`` as the default view.):\n\n >>> browser.getLink('Back to the main page.').click()\n >>> print(browser.url)\n http://localhost/++skin++PageletTestSkin/container/\n >>> print(browser.contents)\n \n \n \n PageletTest\n \n \n Logout\n \n \n\n\nSelecting the displayed logout link drops authentication information\nand displays a confirmation page, which redirects to the default page\nwhere the login link is displayed again:\n\n >>> logout_url = browser.getLink('Logout').url\n >>> browser.getLink('Logout').click()\n >>> print(browser.contents)\n \n \n \n PageletTest\n \n \n \n \n Logout\n
\n

You are being redirected!

\n \n

\n \n If you see this screen for more than 5 seconds, click here.\n \n

\n
\n \n \n >>> browser.getLink('If you see this screen for more than 5 seconds').click()\n >>> print(browser.contents)\n \n \n \n PageletTest\n \n \n Login\n \n \n\nCalling the logout URL again after logout leads directly to the page\nreferred in nextURL:\n\n >>> browser.open(logout_url)\n >>> print(browser.url)\n http://localhost/++skin++PageletTestSkin/container/@@default.html\n >>> print(browser.contents)\n \n \n \n PageletTest\n \n \n Login\n \n \n\nCalling the logout URL again without the query parameter leeds to a\nconfirmation page telling that logout was successfull:\n\n >>> browser.open(logout_url.split('?')[0])\n >>> print(browser.url)\n http://localhost/++skin++PageletTestSkin/container/@@logout.html\n >>> print(browser.contents)\n \n \n \n PageletTest\n \n \n \n Login\n
\n

Logout successful!

\n

\n You are now logged out.\n

\n Back to the main page.\n
\n \n \n\n\nChanges\n-------\n\n1.1 (2018-10-18)\n~~~~~~~~~~~~~~~~\n\n- Add support for Python 3.7.\n\n\n1.0.1 (2017-06-08)\n~~~~~~~~~~~~~~~~~~\n\n- Fix dependencies declared in `setup.py`.\n\n\n1.0 (2017-06-07)\n~~~~~~~~~~~~~~~~\n\n- Update to Python 3. Now supporting: Python 3.4 to 3.6, PyPy2 and PyPy3.\n\n- Update the tests to `zope.testbrowser >= 5.0`.\n\n\n0.8.0 (2010-10-13)\n~~~~~~~~~~~~~~~~~~\n\n- Adapted test set up to the changes in `z3c.layer.pagelet` 1.9 thus\n requiring at least this version now.\n\n- Moved code from page template of session credentials login page to view\n class so it can be customized. (Taken from\n `zope.app.authentication.browser.loginform.LoginForm`.) Moved view class\n ``SessionCredentialsLoginForm`` from `z3c.authviewlet.auth` to\n `z3c.authviewlet.session`.\n\n0.7.0 (2009-12-27)\n~~~~~~~~~~~~~~~~~~\n\n- Moved files in `z3c.authviewlet.browser` to `z3c.authviewlet` as\n we only have browser code in this package.\n\n- Broke dependency on `zope.app.publisher` by defining our own\n ``ILogin`` interface.\n\n0.6.0 (2009-12-24)\n~~~~~~~~~~~~~~~~~~\n\n- Added `i18n domains` to allow translation (done in `z3c.locales` package).\n\n0.5.0 (2009-11-30)\n~~~~~~~~~~~~~~~~~~\n\n- Moved authentication viewlet implementation from `z3c.layer.pagelet`\n to this package.\n\n- Initial release.", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/zopefoundation/z3c.authviewlet", "keywords": "z3c authentication viewlet zope zope3", "license": "ZPL 2.1", "maintainer": "", "maintainer_email": "", "name": "z3c.authviewlet", "package_url": "https://pypi.org/project/z3c.authviewlet/", "platform": "", "project_url": "https://pypi.org/project/z3c.authviewlet/", "project_urls": { "Homepage": "https://github.com/zopefoundation/z3c.authviewlet" }, "release_url": "https://pypi.org/project/z3c.authviewlet/1.1/", "requires_dist": null, "requires_python": "", "summary": "Authentication viewlet for Zope3", "version": "1.1" }, "last_serial": 4391396, "releases": { "0.5.0": [ { "comment_text": "", "digests": { "md5": "9c86669f6650f8468e7abbf044b6c817", "sha256": "20d70b2cdc5f2ac58bfd3881d82b536c175b162c33463ebc4ceaf043bc8b73e2" }, "downloads": -1, "filename": "z3c.authviewlet-0.5.0.zip", "has_sig": false, "md5_digest": "9c86669f6650f8468e7abbf044b6c817", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26567, "upload_time": "2009-11-30T17:15:28", "url": "https://files.pythonhosted.org/packages/71/34/9a379d63b2ac83ca37d49a27dd43563d9849df17fa1e73aabaed013ca4f8/z3c.authviewlet-0.5.0.zip" } ], "0.6.0": [ { "comment_text": "", "digests": { "md5": "7cbe8415bf640337a6201340dde8a0ab", "sha256": "a41790269546683d8d5f99d392b622daf0ce20ce9250151da7e944c48417cc10" }, "downloads": -1, "filename": "z3c.authviewlet-0.6.0.tar.gz", "has_sig": false, "md5_digest": "7cbe8415bf640337a6201340dde8a0ab", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15712, "upload_time": "2009-12-24T07:28:36", "url": "https://files.pythonhosted.org/packages/ca/a6/93d54bb5a71eb1b0ced5c6b3ead2c57f2e23a5075678c891678059fa5d0b/z3c.authviewlet-0.6.0.tar.gz" } ], "0.7.0": [ { "comment_text": "", "digests": { "md5": "1c1084f3baf77dabc6b68fec38a9b5b0", "sha256": "c19cb85509c54f4593680963db97d659c721441333345a6edd80aa53c2ac946d" }, "downloads": -1, "filename": "z3c.authviewlet-0.7.0.tar.gz", "has_sig": false, "md5_digest": "1c1084f3baf77dabc6b68fec38a9b5b0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15482, "upload_time": "2009-12-27T14:30:20", "url": "https://files.pythonhosted.org/packages/68/96/f4a763ea147b0365625b81a052c8c9a3127c1dc9d9d1048ab91944bfefe3/z3c.authviewlet-0.7.0.tar.gz" } ], "0.8.0": [ { "comment_text": "", "digests": { "md5": "393e7801edf8bd4d880f72cb5447983e", "sha256": "3fd7d53cf23decbff9d7b2de1dc5c7dbf6326c4b5db21dad1ea76430fac085dd" }, "downloads": -1, "filename": "z3c.authviewlet-0.8.0.tar.gz", "has_sig": false, "md5_digest": "393e7801edf8bd4d880f72cb5447983e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16134, "upload_time": "2010-10-13T18:08:13", "url": "https://files.pythonhosted.org/packages/90/e8/7f3c293b872bb5282c0c0f654d14d7a45d9143f093222eb2ea82462fc9c1/z3c.authviewlet-0.8.0.tar.gz" } ], "1.0": [ { "comment_text": "", "digests": { "md5": "d2cb8a28aeefa585fd7412648fb562a2", "sha256": "f58418ae19332049861c3e7a1581abfc5046131190233e1d4b240e2c33864afa" }, "downloads": -1, "filename": "z3c.authviewlet-1.0.tar.gz", "has_sig": false, "md5_digest": "d2cb8a28aeefa585fd7412648fb562a2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18896, "upload_time": "2017-06-07T18:16:52", "url": "https://files.pythonhosted.org/packages/a9/02/ab20016c7940d7dc78357d37f65d219a52c8f524c33ff3f6e02043fd561a/z3c.authviewlet-1.0.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "9585b8a134dc38fb06761072fa8c371c", "sha256": "555687b930a1cb0a73682ba968a206d948043c4e060dfa9e125b6875c94bd299" }, "downloads": -1, "filename": "z3c.authviewlet-1.0.1.tar.gz", "has_sig": false, "md5_digest": "9585b8a134dc38fb06761072fa8c371c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19093, "upload_time": "2017-06-08T06:48:11", "url": "https://files.pythonhosted.org/packages/0c/2f/57a1a5a41ecc328906029cf59bf3e9c55ea72a1f14c9d5bd8c034db95281/z3c.authviewlet-1.0.1.tar.gz" } ], "1.1": [ { "comment_text": "", "digests": { "md5": "f7a6b3fcdb40b15faafafebaa7d98d6d", "sha256": "3a30f96aeea813861dce18ca1de5e8d62d38d92dccb4b5ffa17f162b6714d024" }, "downloads": -1, "filename": "z3c.authviewlet-1.1.tar.gz", "has_sig": false, "md5_digest": "f7a6b3fcdb40b15faafafebaa7d98d6d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18043, "upload_time": "2018-10-18T18:24:55", "url": "https://files.pythonhosted.org/packages/82/f5/9bdcff9ee4ce0c53d0881a420847731da4c559cef8801dfcc2979755dec1/z3c.authviewlet-1.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "f7a6b3fcdb40b15faafafebaa7d98d6d", "sha256": "3a30f96aeea813861dce18ca1de5e8d62d38d92dccb4b5ffa17f162b6714d024" }, "downloads": -1, "filename": "z3c.authviewlet-1.1.tar.gz", "has_sig": false, "md5_digest": "f7a6b3fcdb40b15faafafebaa7d98d6d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18043, "upload_time": "2018-10-18T18:24:55", "url": "https://files.pythonhosted.org/packages/82/f5/9bdcff9ee4ce0c53d0881a420847731da4c559cef8801dfcc2979755dec1/z3c.authviewlet-1.1.tar.gz" } ] }