Skip to content

Commit

Permalink
Merge pull request #34 from plone/python3
Browse files Browse the repository at this point in the history
More python 3 issues
  • Loading branch information
jensens authored Sep 14, 2018
2 parents 3172fb8 + 7c7ac62 commit ca2496c
Show file tree
Hide file tree
Showing 31 changed files with 355 additions and 173 deletions.
17 changes: 16 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,26 @@ Breaking changes:

New features:

- Make imports work with python 3. Fix startup.
- Make it work in Python 3:
Make imports work.
Fix startup.
Fix setting the auth-cookie.
Fix assignment of MemberData-functions during startup.
User properties are text.
Fix scaling user profile.
Migrate all tests away from PloneTestCasei.
Fix other tests.
[pbauer]

Bug fixes:

- InitializeClass was moved to AccessControl.class_init
[jensens]

- setDefaultRoles is deprecated.
addPermission from AccessControl.Permission is used.
[jensens]

- Removed ``Extensions/Install.py`` which had only backwards compatibility imports.
[maurits]

Expand Down
4 changes: 3 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
'setuptools',
'six',
'zope.deprecation',
'Zope2 >=2.13.22',
'Zope',
]

setup(
Expand All @@ -35,6 +35,8 @@
"License :: OSI Approved :: Zope Public License",
"Programming Language :: Python",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
],
keywords='Zope CMF Plone PAS authentication',
author='Kapil Thangavelu, Wichert Akkerman',
Expand Down
12 changes: 6 additions & 6 deletions src/Products/PlonePAS/permissions.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
# -*- coding: utf-8 -*-
from Products.CMFCore.permissions import setDefaultRoles
from AccessControl.Permission import addPermission

AddGroups = 'Add Groups'
setDefaultRoles(AddGroups, ('Manager',))
addPermission(AddGroups, default_roles=('Manager',))

ManageGroups = 'Manage Groups'
setDefaultRoles(ManageGroups, ('Manager',))
addPermission(ManageGroups, default_roles=('Manager',))

ViewGroups = 'View Groups'
setDefaultRoles(ViewGroups, ('Manager', 'Owner', 'Member'))
addPermission(ViewGroups, default_roles=('Manager', 'Owner', 'Member'))

DeleteGroups = 'Delete Groups'
setDefaultRoles(DeleteGroups, ('Manager', ))
addPermission(DeleteGroups, default_roles=('Manager', ))

SetGroupOwnership = 'Set Group Ownership'
setDefaultRoles(SetGroupOwnership, ('Manager', 'Owner'))
addPermission(SetGroupOwnership, default_roles=('Manager', 'Owner'))
2 changes: 1 addition & 1 deletion src/Products/PlonePAS/plugins/autogroup.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from App.class_init import InitializeClass
from AccessControl.class_init import InitializeClass
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from Products.PlonePAS.interfaces.group import IGroupIntrospection
from Products.PluggableAuthService.PropertiedUser import PropertiedUser
Expand Down
8 changes: 6 additions & 2 deletions src/Products/PlonePAS/plugins/cookie_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from AccessControl.SecurityManagement import getSecurityManager
from Acquisition import aq_base
from Acquisition import aq_parent
from App.class_init import InitializeClass
from AccessControl.class_init import InitializeClass
from App.special_dtml import DTMLFile
from base64 import encodestring
from Products.PluggableAuthService.interfaces.authservice import \
Expand Down Expand Up @@ -70,7 +70,11 @@ def updateCredentials(self, request, response, login, new_password):

setAuthCookie = getattr(self, 'setAuthCookie', None)
if setAuthCookie:
cookie_val = encodestring('%s:%s' % (login, new_password))
cookie_str = b':'.join([
login.encode('utf-8'),
new_password.encode('utf-8'),
])
cookie_val = encodestring(cookie_str)
cookie_val = cookie_val.rstrip()
setAuthCookie(response, self.cookie_name, quote(cookie_val))
else:
Expand Down
2 changes: 1 addition & 1 deletion src/Products/PlonePAS/plugins/crumbler.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"""
from AccessControl.SecurityInfo import ClassSecurityInfo
from Acquisition import aq_base
from App.class_init import InitializeClass
from AccessControl.class_init import InitializeClass
from App.special_dtml import DTMLFile
from OFS.Folder import Folder
from Products.CMFCore.CookieCrumbler import manage_addCC
Expand Down
2 changes: 1 addition & 1 deletion src/Products/PlonePAS/plugins/group.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"""
from AccessControl import ClassSecurityInfo
from App.class_init import InitializeClass
from AccessControl.class_init import InitializeClass
from App.special_dtml import DTMLFile
from BTrees.OOBTree import OOBTree
from BTrees.OOBTree import OOSet
Expand Down
2 changes: 1 addition & 1 deletion src/Products/PlonePAS/plugins/local_role.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from AccessControl import ClassSecurityInfo
from Acquisition import aq_inner
from Acquisition import aq_parent
from App.class_init import InitializeClass
from AccessControl.class_init import InitializeClass
from App.special_dtml import DTMLFile
from Products.PlonePAS.interfaces.plugins import ILocalRolesPlugin
from Products.PluggableAuthService.plugins.LocalRolePlugin \
Expand Down
2 changes: 1 addition & 1 deletion src/Products/PlonePAS/plugins/passwordpolicy.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Mutable Property Provider
"""
from AccessControl import ClassSecurityInfo
from App.class_init import InitializeClass
from AccessControl.class_init import InitializeClass
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from Products.PluggableAuthService.interfaces.plugins import IValidationPlugin
from Products.PluggableAuthService.plugins.BasePlugin import BasePlugin
Expand Down
2 changes: 1 addition & 1 deletion src/Products/PlonePAS/plugins/property.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Mutable Property Provider
"""
from AccessControl import ClassSecurityInfo
from App.class_init import InitializeClass
from AccessControl.class_init import InitializeClass
from App.special_dtml import DTMLFile
from BTrees.OOBTree import OOBTree
from Products.CMFCore.utils import getToolByName
Expand Down
2 changes: 1 addition & 1 deletion src/Products/PlonePAS/plugins/role.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from Acquisition import aq_get
from Acquisition import aq_inner
from Acquisition import aq_parent
from App.class_init import InitializeClass
from AccessControl.class_init import InitializeClass
from App.special_dtml import DTMLFile
from Products.PlonePAS.interfaces.capabilities import IAssignRoleCapability
from Products.PlonePAS.utils import getGroupsForPrincipal
Expand Down
6 changes: 3 additions & 3 deletions src/Products/PlonePAS/plugins/ufactory.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from AccessControl import ClassSecurityInfo
from AccessControl.PermissionRole import _what_not_even_god_should_do
from App.class_init import InitializeClass
from AccessControl.class_init import InitializeClass
from App.special_dtml import DTMLFile
from Products.PlonePAS.interfaces.plugins import ILocalRolesPlugin
from Products.PlonePAS.interfaces.propertysheets import IMutablePropertySheet
Expand Down Expand Up @@ -215,7 +215,7 @@ def setProperties(self, properties=None, **kw):
continue

update = {}
for (key, value) in properties.items():
for (key, value) in list(properties.items()):
if sheet.hasProperty(key):
update[key] = value
del properties[key]
Expand All @@ -227,7 +227,7 @@ def getProperty(self, id, default=_marker):
for sheet in self.getOrderedPropertySheets():
if sheet.hasProperty(id):
value = sheet.getProperty(id)
if isinstance(value, six.text_type):
if six.PY2 and isinstance(value, six.text_type):
# XXX Temporarily work around the fact that
# property sheets blindly store and return
# unicode. This is sub-optimal and should be
Expand Down
2 changes: 1 addition & 1 deletion src/Products/PlonePAS/plugins/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from AccessControl import AuthEncoding
from AccessControl import ClassSecurityInfo
from AccessControl.Permissions import manage_users as ManageUsers
from App.class_init import InitializeClass
from AccessControl.class_init import InitializeClass
from App.special_dtml import DTMLFile
from Products.PlonePAS.interfaces.capabilities import IDeleteCapability
from Products.PlonePAS.interfaces.capabilities import IPasswordSetCapability
Expand Down
52 changes: 52 additions & 0 deletions src/Products/PlonePAS/testing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
from plone.app.contenttypes.testing import PLONE_APP_CONTENTTYPES_FIXTURE
from plone.app.testing import setRoles
from plone.app.testing import TEST_USER_ID
from plone.app.testing import applyProfile
from plone.app.testing import FunctionalTesting
from plone.app.testing import IntegrationTesting
from plone.app.testing import PloneSandboxLayer
from plone.testing import z2

import Products.PlonePAS


class ProductsPlonepasLayer(PloneSandboxLayer):

defaultBases = (PLONE_APP_CONTENTTYPES_FIXTURE,)

def setUpZope(self, app, configurationContext):
# Load any other ZCML that is required for your tests.
# The z3c.autoinclude feature is disabled in the Plone fixture base
# layer.
self.loadZCML(package=Products.PlonePAS)
z2.installProduct(app, 'Products.PlonePAS')

def setUpPloneSite(self, portal):
applyProfile(portal, 'Products.PlonePAS:PlonePAS')
# setRoles(portal, TEST_USER_ID, ['Manager'])
from Products.CMFPlone.utils import _createObjectByType
_createObjectByType('Folder', portal, id='Members')
mtool = portal.portal_membership
if not mtool.getMemberareaCreationFlag():
mtool.setMemberareaCreationFlag()
mtool.createMemberArea(TEST_USER_ID)
if mtool.getMemberareaCreationFlag():
mtool.setMemberareaCreationFlag()

_createObjectByType('Folder', portal, id='folder')


PRODUCTS_PLONEPAS_FIXTURE = ProductsPlonepasLayer()


PRODUCTS_PLONEPAS_INTEGRATION_TESTING = IntegrationTesting(
bases=(PRODUCTS_PLONEPAS_FIXTURE,),
name='ProductsPlonepasLayer:IntegrationTesting',
)


PRODUCTS_PLONEPAS_FUNCTIONAL_TESTING = FunctionalTesting(
bases=(PRODUCTS_PLONEPAS_FIXTURE,),
name='ProductsPlonepasLayer:FunctionalTesting',
)
3 changes: 0 additions & 3 deletions src/Products/PlonePAS/tests/base.py

This file was deleted.

22 changes: 11 additions & 11 deletions src/Products/PlonePAS/tests/cookie_auth.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ User in Plone Site
Plone Site has PAS installed

>>> portal = layer['portal']
>>> print portal.acl_users.meta_type
>>> print(portal.acl_users.meta_type)
Pluggable Auth Service

User exists in the user folder inside the Plone Site.

>>> uf = portal.acl_users
>>> print uf.meta_type
>>> print(uf.meta_type)
Pluggable Auth Service

>>> user_name, user_password, user_role = ('foo', 'bar', 'Manager')
Expand All @@ -32,7 +32,7 @@ Login to Plone Site using Basic Auth works.
>>> browser = Browser(layer['app'])
>>> browser.addHeader('Authorization', 'Basic %s:%s' % (TEST_USER_NAME, TEST_USER_PASSWORD,))
>>> browser.open('%s/manage' % portal.absolute_url())
>>> print browser.headers
>>> print(browser.headers)
Status: 200 ...

Make sure cookie plugin is installed and activated.
Expand All @@ -53,13 +53,13 @@ Make sure cookie plugin is installed and activated.
... pass

>>> for active, iface in actives:
... print iface,
... print(iface)
... for id, plugin in active:
... if id == 'credentials_cookie_auth':
... print True
<...IExtraction...> True
<...IChallenge...> True
<...ICredentialsUpdate...> <...ICredentialsReset...>
... print(True)
<...IExtraction...>...True
<...IChallenge...>...True
<...ICredentialsUpdate...>...<...ICredentialsReset...>

User in parent folder
---------------------
Expand All @@ -68,7 +68,7 @@ User Exists on the folder containing the Plone Site, which should be a
Pluggable Auth Service too.

>>> uf = layer['app'].acl_users
>>> print uf.meta_type
>>> print(uf.meta_type)
Pluggable Auth Service

>>> user_name, user_password, user_role = ('baz', 'bar', 'Manager')
Expand All @@ -85,14 +85,14 @@ Login directly to containing folder using Basic Auth works.
>>> browser = Browser(layer['app'])
>>> browser.addHeader('Authorization', 'Basic %s:%s' % (user_name, user_password,))
>>> browser.open('%s/manage' % layer['app'].absolute_url())
>>> print browser.headers
>>> print(browser.headers)
Status: 200 ...

Login to Plone Site using Basic Auth works.

>>> browser = Browser(layer['app'])
>>> browser.addHeader('Authorization', 'Basic %s:%s' % (user_name, user_password,))
>>> browser.open('%s/manage' % portal.absolute_url())
>>> print browser.headers
>>> print(browser.headers)
Status: 200 ...

6 changes: 3 additions & 3 deletions src/Products/PlonePAS/tests/dummy.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
from OFS.SimpleItem import SimpleItem
from six import StringIO
from six import BytesIO
from ZPublisher.HTTPRequest import FileUpload

TEXT = 'file data'
TEXT = b'file data'


class FieldStorage(object):
Expand Down Expand Up @@ -33,7 +33,7 @@ def __init__(self, filename=None, data=None, headers=None):
self.data = data
if headers is not None:
self.headers = headers
self.file = StringIO(self.data)
self.file = BytesIO(self.data)

def seek(self, *args):
pass
Expand Down
30 changes: 16 additions & 14 deletions src/Products/PlonePAS/tests/test_basic_ops.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
# -*- coding: utf-8 -*-
from Products.PlonePAS.tests import base
from Products.PluggableAuthService.PluggableAuthService import \
_SWALLOWABLE_PLUGIN_EXCEPTIONS
from Products.PluggableAuthService.interfaces.authservice import \
IPluggableAuthService
from Products.PluggableAuthService.interfaces.events import \
IPrincipalDeletedEvent
from plone.app.testing import setRoles
from plone.app.testing import TEST_USER_ID
from Products.PlonePAS.testing import PRODUCTS_PLONEPAS_INTEGRATION_TESTING
from Products.PluggableAuthService.interfaces.authservice import IPluggableAuthService
from Products.PluggableAuthService.interfaces.events import IPrincipalDeletedEvent
from Products.PluggableAuthService.interfaces.plugins import IRolesPlugin
from Products.PluggableAuthService.PluggableAuthService import _SWALLOWABLE_PLUGIN_EXCEPTIONS
from zope.component import adapter
from zope.component import getGlobalSiteManager

import unittest

class BasicOpsTestCase(base.TestCase):

def afterSetUp(self):
self.loginAsPortalOwner()
class BasicOpsTestCase(unittest.TestCase):

layer = PRODUCTS_PLONEPAS_INTEGRATION_TESTING

def setUp(self):
self.portal = self.layer['portal']
setRoles(self.portal, TEST_USER_ID, ['Manager'])
self.acl_users = self.portal.acl_users

def compareRoles(self, target, user, roles):
Expand All @@ -32,11 +36,9 @@ def compareRoles(self, target, user, roles):
user_roles = list(u.getRoles())
else:
user_roles = list(u.getRolesInContext(target))
actual_roles = filter(lambda x: x not in non_roles, user_roles)
actual_roles.sort()
actual_roles = list(filter(lambda x: x not in non_roles, user_roles))
wished_roles = list(roles)
wished_roles.sort()
if actual_roles == wished_roles:
if sorted(actual_roles) == sorted(wished_roles):
return 1
raise RuntimeError("User %s: Whished roles: %s BUT current "
"roles: %s" % (user, wished_roles, actual_roles))
Expand Down
Loading

0 comments on commit ca2496c

Please sign in to comment.