Skip to content

Commit

Permalink
Fix NameError in idpicker.py on Python 3.
Browse files Browse the repository at this point in the history
Fixes #7.

Also a number of small updates:

- Run all the doctests.
- Enable test coverage reporting.
- Add support for Python 3.6.
- Modernize tox.ini
- Use pip on Travis and enable Travis caching.
- Run all doctests with consistent flags and checker
- Use renormalizing.IGNORE_EXCEPTION_MODULE_IN_PYTHON2 instead of
  manually normalizing one exception
- Rename .txt to .rst and include them in the published docs. Fix
  headers to be consistent to enable this.
- List PyPy in the classifiers.
  • Loading branch information
jamadden committed Apr 30, 2017
1 parent a1b42a4 commit 9d8bd7d
Show file tree
Hide file tree
Showing 14 changed files with 166 additions and 143 deletions.
7 changes: 7 additions & 0 deletions .coveragerc
@@ -0,0 +1,7 @@
[run]
source = src

[report]
exclude_lines =
pragma: no cover
if __name__ == '__main__':
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -8,3 +8,5 @@ eggs/
develop-eggs/
dist/
parts/
.coverage
htmlcov/
24 changes: 18 additions & 6 deletions .travis.yml
Expand Up @@ -5,11 +5,23 @@ python:
- 3.3
- 3.4
- 3.5
- pypy
- pypy3
install:
- pip install tox-travis
- 3.6
- pypy-5.4.1
script:
- tox
- coverage run -m zope.testrunner --test-path=src --auto-color --auto-progress

after_success:
- coveralls
notifications:
email: false
email: false

install:
- pip install -U pip setuptools
- pip install -U coveralls coverage
- pip install -U -e ".[test]"


cache: pip

before_cache:
- rm -f $HOME/.cache/pip/log/debug.log
7 changes: 5 additions & 2 deletions CHANGES.rst
@@ -1,10 +1,13 @@
Changes
=======

2.1.1 (unreleased)
2.2.0 (unreleased)
------------------

- TBD
- Add support for Python 3.6.

- Fix a NameError in the idpicker under Python 3.6.
See `issue 7 <https://github.com/zopefoundation/zope.pluggableauth/issues/7>`_.

2.1.0 (2016-07-04)
------------------
Expand Down
2 changes: 2 additions & 0 deletions MANIFEST.in
Expand Up @@ -3,6 +3,8 @@ include *.txt
include *.py
include buildout.cfg
include tox.ini
include .travis.yml
include .coveragerc

recursive-include src *

Expand Down
5 changes: 3 additions & 2 deletions README.rst
@@ -1,5 +1,6 @@
``zope.pluggableauth``
======================
========================
``zope.pluggableauth``
========================

.. image:: https://travis-ci.org/zopefoundation/zope.pluggableauth.png?branch=master
:target: https://travis-ci.org/zopefoundation/zope.pluggableauth
Expand Down
43 changes: 26 additions & 17 deletions setup.py
Expand Up @@ -28,21 +28,28 @@ def read(*rnames):
with open(os.path.join(os.path.dirname(__file__), *rnames)) as f:
return f.read()

tests_require = [
'zope.testing',
'zope.testrunner',
]

setup(
name='zope.pluggableauth',
version='2.1.1.dev0',
version='2.2.1.dev0',
author='Zope Foundation and Contributors',
author_email='zope-dev@zope.org',
description='Pluggable Authentication Utility',
long_description= "\n\n".join((
read('README.rst'),
read('src', 'zope', 'pluggableauth', 'README.txt'),
read('CHANGES.rst'),
)),
read('README.rst'),
read('src', 'zope', 'pluggableauth', 'README.rst'),
read('src', 'zope', 'pluggableauth', 'plugins', 'principalfolder.rst'),
read('src', 'zope', 'pluggableauth', 'plugins', 'groupfolder.rst'),
read('CHANGES.rst'),
)),
url='http://pypi.python.org/pypi/zope.pluggableauth',
license='ZPL 2.1',
keywords='zope3 ztk authentication pluggable',
classifiers = [
classifiers=[
'Development Status :: 5 - Production/Stable',
'Environment :: Web Environment',
'Intended Audience :: Developers',
Expand All @@ -54,18 +61,20 @@ def read(*rnames):
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Natural Language :: English',
'Operating System :: OS Independent',
'Topic :: Internet :: WWW/HTTP',
'Framework :: Zope3'],
'Framework :: Zope3'
],
packages=find_packages('src'),
package_dir = {'': 'src'},
package_dir={'': 'src'},
namespace_packages=['zope'],
extras_require=dict(test=[
'zope.testing',
#'zope.component[test]' # Pulls in ZODB3 right now. :-(
]),
extras_require={
'test': tests_require,
},
install_requires=[
'persistent',
'setuptools',
Expand All @@ -83,9 +92,9 @@ def read(*rnames):
'zope.session',
'zope.site',
'zope.traversing',
],
tests_require=['zope.testing'],
],
tests_require=tests_require,
test_suite='zope.pluggableauth.tests.test_suite',
include_package_data = True,
zip_safe = False,
)
include_package_data=True,
zip_safe=False,
)
8 changes: 1 addition & 7 deletions src/zope/__init__.py
@@ -1,7 +1 @@
# this is a namespace package
try:
import pkg_resources
pkg_resources.declare_namespace(__name__)
except ImportError:
import pkgutil
__path__ = pkgutil.extend_path(__path__, __name__)
__import__('pkg_resources').declare_namespace(__name__) # pragma: no cover
@@ -1,5 +1,6 @@
Pluggable-Authentication Utility
================================
==================================
Pluggable-Authentication Utility
==================================

The Pluggable-Authentication Utility (PAU) provides a framework for
authenticating principals and associating information with them. It uses
Expand All @@ -10,7 +11,7 @@ registered as a utility providing the
`zope.authentication.interfaces.IAuthentication` interface.

Authentication
--------------
==============

The primary job of PAU is to authenticate principals. It uses two types of
plug-ins in its work:
Expand Down Expand Up @@ -42,7 +43,7 @@ the principal. Typically, if a subscriber adds data, it should also add
corresponding interface declarations.

Simple Credentials Plugin
~~~~~~~~~~~~~~~~~~~~~~~~~
-------------------------

To illustrate, we'll create a simple credentials plugin:

Expand All @@ -67,7 +68,7 @@ As a plugin, MyCredentialsPlugin needs to be registered as a named utility:
>>> provideUtility(myCredentialsPlugin, name='My Credentials Plugin')

Simple Authenticator Plugin
~~~~~~~~~~~~~~~~~~~~~~~~~~~
---------------------------

Next we'll create a simple authenticator plugin. For our plugin, we'll need
an implementation of IPrincipalInfo:
Expand Down Expand Up @@ -102,7 +103,7 @@ as a named utility:
>>> provideUtility(myAuthenticatorPlugin, name='My Authenticator Plugin')

Configuring a PAU
~~~~~~~~~~~~~~~~~
-----------------

Finally, we'll create the PAU itself:

Expand All @@ -115,7 +116,7 @@ and configure it with the two plugins:
>>> pau.authenticatorPlugins = ('My Authenticator Plugin', )

Using the PAU to Authenticate
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-----------------------------

>>> from zope.pluggableauth.factories import AuthenticatedPrincipalFactory
>>> provideAdapter(AuthenticatedPrincipalFactory)
Expand All @@ -142,7 +143,7 @@ However, if we provide the proper credentials:
we get an authenticated principal.

Multiple Authenticator Plugins
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
------------------------------

The PAU works with multiple authenticator plugins. It uses each plugin, in the
order specified in the PAU's authenticatorPlugins attribute, to authenticate
Expand Down Expand Up @@ -193,7 +194,7 @@ The second plugin, however, gets a chance to authenticate if first does not:
Principal('xyz_white')

Multiple Credentials Plugins
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
----------------------------

As with with authenticators, we can specify multiple credentials plugins. To
illustrate, we'll create a credentials plugin that extracts credentials from
Expand Down Expand Up @@ -290,7 +291,7 @@ This highlights PAU's ability to use multiple plugins for authentication:
cheers!)

Multiple Authenticator Plugins
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
------------------------------

As with the other operations we've seen, the PAU uses multiple plugins to
find a principal. If the first authenticator plugin can't find the requested
Expand Down Expand Up @@ -371,7 +372,7 @@ we get a different principal for ID 'white':


Issuing a Challenge
-------------------
===================

Part of PAU's IAuthentication contract is to challenge the user for
credentials when its 'unauthorized' method is called. The need for this
Expand Down Expand Up @@ -452,7 +453,7 @@ the advanced plugin is used because it's first:
'advancedlogin.html'

Challenge Protocols
~~~~~~~~~~~~~~~~~~~
-------------------

Sometimes, we want multiple challengers to work together. For example, the
HTTP specification allows multiple challenges to be issued in a response. A
Expand Down Expand Up @@ -510,7 +511,7 @@ first plugin:


Pluggable-Authentication Prefixes
---------------------------------
=================================

Principal ids are required to be unique system wide. Plugins will often provide
options for providing id prefixes, so that different sets of plugins provide
Expand Down
@@ -1,6 +1,6 @@
=============
Group Folders
=============
===============
Group Folders
===============

Group folders provide support for groups information stored in the ZODB. They
are persistent, and must be contained within the PAUs that use them.
Expand Down Expand Up @@ -187,8 +187,7 @@ Groups cannot contain cycles:
... # doctest: +NORMALIZE_WHITESPACE
Traceback (most recent call last):
...
GroupCycle: (u'auth.group.G2',
[u'auth.group.G2', u'auth.group.G1'])
zope.pluggableauth.plugins.groupfolder.GroupCycle: (u'auth.group.G2', [u'auth.group.G2', u'auth.group.G1'])

Trying to do so does not fire an event.

Expand Down Expand Up @@ -236,7 +235,7 @@ If you don't supply a search key, no results will be returned:
[]

Identifying groups
------------------
==================
The function, `setGroupsForPrincipal`, is a subscriber to
principal-creation events. It adds any group-folder-defined groups to
users in those groups:
Expand Down Expand Up @@ -266,7 +265,7 @@ function also declares the `IGroup` interface on groups:
['IGroupAwarePrincipal']

Special groups
--------------
==============
Two special groups, Authenticated, and Everyone may apply to users
created by the pluggable-authentication utility. There is a
subscriber, specialGroups, that will set these groups on any non-group
Expand Down Expand Up @@ -345,7 +344,7 @@ And they are only added to group aware principals:
[]

Member-aware groups
-------------------
===================
The groupfolder includes a subscriber that gives group principals the
zope.security.interfaces.IGroupAware interface and an implementation thereof.
This allows groups to be able to get and set their members.
Expand Down Expand Up @@ -397,7 +396,7 @@ The two methods work with the value on the IGroupInformation object.
True

Limitation
==========
----------

The current group-folder design has an important limitation!

Expand Down
18 changes: 12 additions & 6 deletions src/zope/pluggableauth/plugins/idpicker.py
Expand Up @@ -14,7 +14,6 @@
##############################################################################
"""Helper base class that picks principal ids
$Id: idpicker.py 117492 2010-10-13 08:17:55Z janwijbrand $
"""
__docformat__ = 'restructuredtext'

Expand All @@ -23,9 +22,16 @@
from zope.exceptions.interfaces import UserError
from zope.i18nmessageid import MessageFactory

try:
text_type = unicode
except NameError: # py3
text_type = str

_ = MessageFactory('zope')

ok = re.compile('[!-~]+$').match


class IdPicker(NameChooser):
"""Helper base class that picks principal ids.
Expand Down Expand Up @@ -53,11 +59,11 @@ class IdPicker(NameChooser):
"""
def chooseName(self, name, object):
i = 0
name = unicode(name)
name = text_type(name)
orig = name
while (not name) or (name in self.context):
i += 1
name = orig+str(i)
name = orig + str(i)

self.checkName(name, object)
return name
Expand All @@ -76,14 +82,14 @@ def checkName(self, name, object):
>>> try:
... IdPicker({}).checkName(u'bob\xfa', None)
... except UserError, e:
... except UserError as e:
... print(e)
... # doctest: +NORMALIZE_WHITESPACE
Ids must contain only printable 7-bit non-space ASCII characters
>>> try:
... IdPicker({}).checkName(u'big bob', None)
... except UserError, e:
... except UserError as e:
... print(e)
... # doctest: +NORMALIZE_WHITESPACE
Ids must contain only printable 7-bit non-space ASCII characters
Expand All @@ -96,7 +102,7 @@ def checkName(self, name, object):
>>> IdPicker({}).checkName(u'x' * 101, None)
Traceback (most recent call last):
...
UserError: Ids can't be more than 100 characters long.
zope.exceptions.interfaces.UserError: Ids can't be more than 100 characters long.
"""
NameChooser.checkName(self, name, object)
Expand Down

0 comments on commit 9d8bd7d

Please sign in to comment.