In Plone, there are two loosely coupled member related subsystems
The following view method code will get the username for the logged in user.
Example:
from Products.CMFCore.utils import getToolByName
def getActiveUser(self):
"""
"""
mt = getToolByName(self.context, 'portal_membership')
if mt.isAnonymousUser(): # the user has not logged in
return None
else:
member = mt.getAuthenticatedMember()
username = member.getUserName()
return username
or in template:
username context/portal_membership/getAuthenticatedMember/getUserName
These examples could have used getToolByName(self.context, ‘acl_users’)
To get a member by username (you must have ‘manager’ role):
member = self.context.acl_users.getUserById(username)
To get all usernames:
memberIds = self.context.acl_users.getUserIds()
Example:
buffer = ""
# Returns list of site usernames
users = context.acl_users.getUserNames()
# alternative: get user objects
#users = context.acl_users.getUsers()
for user in users:
print "Got username:" + user
ノート
Zope users, like admin, is not included in this list.
In this example we use the portal_membership tool We assume that a role called ‘Agent’ exists and we already have the context:
from Products.CMFCore.utils import getToolByName
mtool = getToolByName(context,'portal_membership')
Agents = [member for member in mtool.listMembers() \
if member.has_role('Agent')]
Groups are stored as PloneGroup objects, which is subclass of PloneUser. Groups are managed by portal_groups tool.
Example:
gr = site.portal_groups
group_id = "companies"
if not group_id in gr.getGroupIds():
gr.addGroup(group_id)
More info
Getting all groups on the site is possible through acl_users and source_groups folder which provide functionality to manipulate Plone groups.
Example to get only ids:
acl_users = site.acl_users
groups = acl.source_groups.getGroupIds() # Iterable of id strings
Example to get full group information:
site = context.portal_url.getPortalObject()
users = site.acl_users
list = users.source_groups.getGroups()
for group in list:
# group is PloneGroup object
yield (group.getName(), group.title)
Example:
# Add user to group "companies"
portal_groups = site.portal_groups
portal_groups.addPrincipalToGroup(member.getUserName(), "companies")
Below is an example how to get groups for the logged in user:
(portal.portal_membership.getAuthenticatedMember().has_role('Manager')) or
('Organizzazione' in portal.portal_membership.getAuthenticatedMember().getGroups())
警告
Deprecation: This method won’t work in Plone 4.
Example:
membership = getToolByName(self, 'portal_membership')
if membership.getMemberById(id) is not None:
return False
return True
See also
Use portal_registration tool. Example:
def createCompany(request, site, username, title, email, passwd=None):
"""
Utility function which performs the actual creation, role and permission magic.
@param username: Unicode string
@param title: Fullname of user, unicode string
@return: Created company content item or None if the creation fails
"""
# If we use custom member properties
# they must be intiialized before regtool is called
prepareMemberProperties(site)
# portal_registrations manages new user creation
regtool = getToolByName(site, 'portal_registration')
# Default password to the username
# ... don't do this on the production server!
if passwd == None:
passwd = username
# Only lowercase allowed
username = username.lower()
# Username must be ASCII string
# or Plone will choke when the user tries to log in
username = str(username)
def is_ascii(s):
for c in s:
if not ord(c) < 128:
return False
return True
if not is_ascii(username):
""" """
IStatusMessage(request).addStatusMessage(_(u"Username must contain only characters a-z"), "error")
return None
# This is minimum required information set
# to create a working member
properties = {
'username' : username,
# Full name must be always as utf-8 encoded
'fullname' : title.encode("utf-8"),
'email' : email,
}
try:
# addMember() returns MemberData object
member = regtool.addMember(username, passwd, properties=properties)
except ValueError, e:
# Give user visual feedback what went wrong
IStatusMessage(request).addStatusMessage(_(u"Could not create the user:") + unicode(e), "error")
return None
Below is an example of Grok form which the administrator can use to create new users. New users will receive special properties and a folder for which they have ownership access. Password is set to be the same as the username. The user is added a group “companies”.
Example company.py:
# -*- coding: utf-8 -*-
"""
Add companies.
Create user account + associated "home folder" content type
for a company user.
User accounts have a special role.
Note: As writing of this 2010-04, needs
plone.app.directives trunk version which
contains unreleased validation decorator
"""
# Core Zope 2 + Zope 3 + Plone
from zope.interface import Interface
from zope import schema
from five import grok
from Products.CMFCore.interfaces import ISiteRoot
from Products.CMFCore.utils import getToolByName
from Products.CMFCore import permissions
from Products.statusmessages.interfaces import IStatusMessage
# Form and validation
from z3c.form import field
import z3c.form.button
from plone.directives import form
from collective.z3cform.grok.grok import PloneFormWrapper
import plone.autoform.form
# Products.validation use some ugly ZService magic which I can't quite comprehend
from Products.validation import validation
# Our translation catalog
from isleofback.app import appMessageFactory as _
grok.templatedir("templates")
class ICompanyCreationFormSchema(form.Schema):
""" Define fields used on the form """
username = schema.TextLine(title=u"Username")
company_name = schema.TextLine(title=u"Company name")
email = schema.TextLine(title=u"Email")
class CompanyCreationForm(plone.autoform.form.AutoExtensibleForm, form.Form):
""" Form action controller.
form.DisplayForm will automatically expose the form
as a view, no wrapping view creation needed.
"""
# Form label
name = _(u"Create Company")
# Which schema is used by AutoExtensibleForm
schema = ICompanyCreationFormSchema
# The form does not care about the context object
# and should not try to extract field value
# defaults out of it
ignoreContext = True
# This form is available at the site root only
grok.context(ISiteRoot)
# z3c.form has a function decorator
# which turns the function to a form button action handler
@z3c.form.button.buttonAndHandler(_('Create Company'), name='create')
def createCompanyAction(self, action):
"""
"""
data, errors = self.extractData()
if errors:
self.status = self.formErrorsMessage
return
obj = createCompany(self.request, self.context, data["username"], data["company_name"], data["email"])
if obj is not None:
# mark only as finished if we get the new object
IStatusMessage(self.request).addStatusMessage(_(u"Company created"), "info")
class CompanyCreationView(PloneFormWrapper):
""" View which exposes form as URL """
form = CompanyCreationForm
# Set up security barrier -
# non-priviledged users can't access this form
grok.require("cmf.ManagePortal")
# Use http://yourhost/@@create_company URL to access this form
grok.name("create_company")
# This view is available at the site root only
grok.context(ISiteRoot)
# Which template is used to decorate the form
# -> forms.pt in template directory
grok.template("form")
@form.validator(field=ICompanyCreationFormSchema['email'])
def validateEmail(value):
"""
Use old Products.validation validators to perform the validation.
"""
validator_function = validation.validatorFor('isEmail')
if not validator_function(value):
raise schema.ValidationError(u"Entered email address is not good:" + value)
def prepareMemberProperties(site):
""" Adjust site for custom member properties """
# Need to use ancient Z2 property sheet API here...
portal_memberdata = getToolByName(site, "portal_memberdata")
# When new member is created, it's MemberData
# is populated with the values from portal_memberdata property sheet,
# so value="" will be the default value for users' home_folder_uid
# member property
if not portal_memberdata.hasProperty("home_folder_uid"):
portal_memberdata.manage_addProperty(id="home_folder_uid", value="", type="string")
# Create a group "companies" where newly created members will be added
acl_users = site.acl_users
#groups = acl_users.source_groups.getGroupIds()
gr = site.portal_groups
group_id = "companies"
if not group_id in gr.getGroupIds():
gr.addGroup(group_id, [], [],
{ 'title': 'Companies'})
def createCompany(request, site, username, title, email, passwd=None):
"""
Utility function which performs the actual creation, role and permission magic.
@param username: Unicode string
@param title: Fullname of user, unicode string
@return: Created company content item or None if the creation fails
"""
# If we use custom member properties
# they must be intiialized before regtool is called
prepareMemberProperties(site)
# portal_registrations manages new user creation
regtool = getToolByName(site, 'portal_registration')
# Default password to the username
# ... don't do this on the production server!
if passwd == None:
passwd = username
# Only lowercase allowed
username = username.lower()
# Username must be ASCII string
# or Plone will choke when the user tries to log in
username = str(username)
def is_ascii(s):
for c in s:
if not ord(c) < 128:
return False
return True
if not is_ascii(username):
""" """
IStatusMessage(request).addStatusMessage(_(u"Username must contain only characters a-z"), "error")
return None
# This is minimum required information set
# to create a working member
properties = {
'username' : username,
# Full name must be always as utf-8 encoded
'fullname' : title.encode("utf-8"),
'email' : email,
}
try:
# addMember() returns MemberData object
member = regtool.addMember(username, passwd, properties=properties)
except ValueError, e:
# Give user visual feedback what went wrong
IStatusMessage(request).addStatusMessage(_(u"Could not create the user:") + unicode(e), "error")
return None
# Add user to group "companies"
portal_groups = site.portal_groups
portal_groups.addPrincipalToGroup(member.getUserName(), "companies")
return createMatchingHomeFolder(request, site, member)
def createMatchingHomeFolder(request, site, member, target_folder="yritykset", target_type="IsleofbackCompany", language="fi"):
""" Creates a folder, sets its ownership for the member and stores the folder UID in the member data.
@param member: MemberData object
@param target_folder: Under which folder a new content item is created
@param language: Initial two language code of the item
"""
parent_folder = site.restrictedTraverse(target_folder)
# Cannot add custom memberdata properties unless explicitly declared
id = member.getUserName()
parent_folder.invokeFactory(target_type, id)
home_folder = parent_folder[id]
name = member.getProperty("fullname")
home_folder.setTitle(name)
home_folder.setLanguage(language)
email = member.getProperty("email")
home_folder.setEmail(email)
# Unset the Archetypes object creation flag
home_folder.processForm()
# Store UID of the created folder in memberdata so we can
# look it up later to e.g. generate the link to the member folder
member.setMemberProperties(mapping={"home_folder_uid": home_folder.UID()})
# Get the user handle from member data object
user = member.getUser()
username = user.getUserName()
home_folder.manage_setLocalRoles(username, ["Owner",])
home_folder.reindexObjectSecurity()
return home_folder