Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Default Roles For Users Configurable #4

Merged
merged 5 commits into from Aug 28, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 21 additions & 8 deletions Products/AutoUserMakerPASPlugin/auth.py
Expand Up @@ -44,6 +44,7 @@
httpSharingTokensKey = 'http_sharing_tokens'
httpSharingLabelsKey = 'http_sharing_labels'
usernameKey = 'user_id'
defaultRolesKey = 'default_roles'

PWCHARS = string.letters + string.digits + string.punctuation

Expand Down Expand Up @@ -93,6 +94,7 @@ def authenticateCredentials(self, credentials):
"""See class's docstring and IAuthenticationPlugin."""

mappings = credentials.pop('_getMappings', [])
defaultRoles = credentials.pop('_defaultRoles', [])
userId = credentials.get(usernameKey, None)

pas = self._getPAS()
Expand Down Expand Up @@ -142,8 +144,11 @@ def authenticateCredentials(self, credentials):
self._updateUserProperties(user, credentials)
break

# Build a list of roles to assign to the user, always with Member
roles = {'Member': True}
# Build a list of roles to assign to the user, starting with the
# default roles (usually at least Member)
roles = {}
for role in defaultRoles:
roles[role] = True
groups = []
if credentials.has_key('filters'):
for role in mappings:
Expand Down Expand Up @@ -283,7 +288,7 @@ class ExtractionPlugin(BasePlugin, PropertyManager):
>>> from Products.AutoUserMakerPASPlugin.auth import ExtractionPlugin
>>> handler = ExtractionPlugin()
>>> handler.extractCredentials(request)
{'user_id': 'foobar', 'description': None, 'location': '', 'filters': {}, 'fullname': None, '_getMappings': [], 'email': None}
{'_defaultRoles': ('Member',), 'user_id': 'foobar', 'description': None, 'location': '', 'filters': {}, 'fullname': None, '_getMappings': [], 'email': None}

"""
security = ClassSecurityInfo()
Expand All @@ -304,7 +309,8 @@ def __init__(self):
(httpSharingTokensKey, 'lines', 'w', []),
(httpSharingLabelsKey, 'lines', 'w', []),
('required_roles', 'lines', 'wd', []),
('login_users', 'lines', 'wd', []))
('login_users', 'lines', 'wd', []),
(defaultRolesKey, 'lines', 'w', ['Member']))
# Create any missing properties
ids = {}
for prop in (config):
Expand Down Expand Up @@ -333,6 +339,7 @@ def getConfig(self):
>>> import pprint
>>> pprint.pprint(handler.getConfig())
{'auto_update_user_properties': 0,
'default_roles': ('Member',),
'http_authz_tokens': (),
'http_commonname': ('HTTP_SHIB_PERSON_COMMONNAME',),
'http_country': ('HTTP_SHIB_ORGPERSON_C',),
Expand All @@ -359,7 +366,8 @@ def getConfig(self):
autoUpdateUserPropertiesKey: self.getProperty(autoUpdateUserPropertiesKey),
httpAuthzTokensKey: self.getProperty(httpAuthzTokensKey),
httpSharingTokensKey: self.getProperty(httpSharingTokensKey),
httpSharingLabelsKey: self.getProperty(httpSharingLabelsKey)}
httpSharingLabelsKey: self.getProperty(httpSharingLabelsKey),
defaultRolesKey: self.getProperty(defaultRolesKey)}

security.declarePublic('getSharingConfig')
def getSharingConfig(self):
Expand Down Expand Up @@ -461,6 +469,10 @@ def loginUsers(self):
"""
return self.getProperty('login_users', [])

security.declarePrivate('defaultRoles')
def defaultRoles(self):
return self.getProperty('default_roles', ['Member'])


security.declarePrivate('extractCredentials')
def extractCredentials(self, request):
Expand Down Expand Up @@ -551,6 +563,7 @@ def extractCredentials(self, request):
return ploneUser

user['_getMappings'] = self.getMappings()
user['_defaultRoles'] = self.defaultRoles()

loginUsers = self.loginUsers()
requiredRoles = self.requiredRoles()
Expand Down Expand Up @@ -621,8 +634,7 @@ def getRoles(self):
True
"""
portalRoleManager = getToolByName(self, 'portal_role_manager')
return [role for role in portalRoleManager.enumerateRoles()
if role['id'] != 'Member']
return portalRoleManager.enumerateRoles()

security.declareProtected(ManageUsers, 'getUsers')
def getUsers(self):
Expand Down Expand Up @@ -713,7 +725,8 @@ def manage_changeConfig(self, REQUEST=None):
autoUpdateUserPropertiesKey: autoupdate,
httpAuthzTokensKey: reqget(httpAuthzTokensKey, ''),
httpSharingTokensKey: reqget(httpSharingTokensKey, ''),
httpSharingLabelsKey: reqget(httpSharingLabelsKey, '')})
httpSharingLabelsKey: reqget(httpSharingLabelsKey, ''),
defaultRolesKey: reqget(defaultRolesKey, '')})
return REQUEST.RESPONSE.redirect('%s/manage_config' %
self.absolute_url())

Expand Down
18 changes: 18 additions & 0 deletions Products/AutoUserMakerPASPlugin/config.zpt
Expand Up @@ -132,6 +132,24 @@
</label>
</p>

<h3 i18n:translate="heading_user_default_roles">User Default Roles</h3>

<p>
<label i18n:translate="description_user_default_roles">
Assign these roles to all new users by default when way login for the first time.
</label>
</p>

<tal:row tal:repeat="role context/getRoles">
<p tal:define="input_id string:default_role_${role/id}">
<input type="checkbox" name="default_roles"
tal:attributes="id input_id;
value role/id;
checked python:role['id'] in config['default_roles'] and 'checked' or None"/>
<label tal:content="role/id" tal:attributes="for input_id">ROLE</label>
</p>
</tal:row>

<h3 i18n:translate="heading_user_mapping_headers">User Mapping Headers</h3>
<p>
<label for="http_authz_tokens" i18n:translate="description_shib_token_list">
Expand Down
3 changes: 1 addition & 2 deletions Products/AutoUserMakerPASPlugin/rolemap.zpt
Expand Up @@ -65,8 +65,7 @@
These values are python regular expressions that will be compiled
as raw strings. See <a href="http://docs.python.org/lib/module-re.html">the
python re module documentation</a> and <a href="http://diveintopython.org/regular_expressions/index.html">Dive
Into Python's Regular Expressions chapter</a>. The member role is
always given. To map an existing user to a Shibboleth user, select
Into Python's Regular Expressions chapter</a>.To map an existing user to a Shibboleth user, select
the existing user id from the drop down list. In this case, roles
given here are ignored (the Shibboleth user gets the already
existing Plone user's roles).
Expand Down
Expand Up @@ -130,6 +130,7 @@ info in the Plone user it creates (which above is just a user id).
... 'HTTP_SHIB_ORGPERSON_STATE': 'NJ',
... 'HTTP_SHIB_ORGPERSON_C': 'US'})
>>> inOrder(apache.extractCredentials(request))
'_defaultRoles':('Member',)
'_getMappings':[]
'description':tester
'email':foo@test.org
Expand All @@ -138,7 +139,6 @@ info in the Plone user it creates (which above is just a user id).
'location':Princeton, NJ, US
'user_id':foo


ZMI Configuration Testing
-------------------------

Expand All @@ -157,6 +157,7 @@ Now, let's check the default configuration:

>>> inOrder(apache.getConfig())
'auto_update_user_properties':0
'default_roles':('Member',)
'http_authz_tokens':()
'http_commonname':('HTTP_SHIB_PERSON_COMMONNAME',)
'http_country':('HTTP_SHIB_ORGPERSON_C',)
Expand Down Expand Up @@ -184,10 +185,12 @@ pseudo REQUEST object, then get the results and print in order.
... "http_country": 'HTTP_TEST_COUNTRY',
... "http_authz_tokens": 'HTTP_TEST_USER',
... "http_sharing_tokens": 'HTTP_TEST_USER',
... "http_sharing_labels": 'TEST_TITLE'})
... "http_sharing_labels": 'TEST_TITLE',
... "default_roles": ['Test Role']})
>>> apache.manage_changeConfig(request)
>>> inOrder(apache.getConfig())
'auto_update_user_properties':0
'default_roles':('Test Role',)
'http_authz_tokens':('HTTP_TEST_USER',)
'http_commonname':('HTTP_TEST_COMMONNAME',)
'http_country':('HTTP_TEST_COUNTRY',)
Expand All @@ -207,6 +210,7 @@ the above output.
>>> request = MockForm({'no_such_field': 'junk'})
>>> inOrder(apache.getConfig())
'auto_update_user_properties':0
'default_roles':('Test Role',)
'http_authz_tokens':('HTTP_TEST_USER',)
'http_commonname':('HTTP_TEST_COMMONNAME',)
'http_country':('HTTP_TEST_COUNTRY',)
Expand Down
12 changes: 12 additions & 0 deletions Products/AutoUserMakerPASPlugin/tests/TestBrowers.txt
Expand Up @@ -39,6 +39,18 @@ Now let's verify the 'strip these domain names' gets set.
>>> browser.getControl(name='strip_domain_name_list').value
'test.org'

See that we can set the default roles for new users. The stock setting should
be only the Member role.

>>> browser.getControl(name='default_roles').value
['Member']
>>> browser.getControl(name='default_roles').options
['Contributor', 'Editor', 'Manager', 'Member', 'Owner', 'Reader', 'Reviewer', 'Site Administrator']
>>> browser.getControl(name='default_roles').value = ['Member', 'Reviewer']
>>> browser.getControl('Save').click()
>>> browser.getControl(name='default_roles').value
['Member', 'Reviewer']

Let's make sure that a user will see an error message when the mapping headers
have not been set.

Expand Down