diff --git a/browser/concept.py b/browser/concept.py index 65b530c..76a4779 100644 --- a/browser/concept.py +++ b/browser/concept.py @@ -68,7 +68,18 @@ class ConceptView(BaseView): @Lazy def macro(self): - return self.template.macros['conceptlisting'] + return self.template.macros['conceptdata'] + + def fieldData(self): + ti = IType(self.context).typeInterface + if not ti: return + adapter = ti(self.context) + for f in ti: + title = getattr(ti[f], 'title', '') + value = getattr(adapter, f, '') + if not (value and title): + continue + yield {'title': title, 'value': value, 'id': f} def children(self): for r in self.context.getChildRelations(): diff --git a/browser/concept_macros.pt b/browser/concept_macros.pt index 7d55c33..ded1490 100644 --- a/browser/concept_macros.pt +++ b/browser/concept_macros.pt @@ -1,4 +1,23 @@ - + +
+

+ Concept: + Title +

+ + + + + +
:
+ +
+
+ + +

@@ -12,7 +31,7 @@
Resource Title + tal:content="related/title">Concept Title

Resource Title + tal:content="related/title">Concept Title
diff --git a/organize/interfaces.py b/organize/interfaces.py index e663378..4bcb9f3 100644 --- a/organize/interfaces.py +++ b/organize/interfaces.py @@ -28,7 +28,10 @@ from zope.app import zapi from zope.app.principalannotation import annotations from zope.app.security.interfaces import IAuthentication, PrincipalLookupError from zope.i18nmessageid import MessageFactory +from zope.security.proxy import removeSecurityProxy + from cybertools.organize.interfaces import IPerson as IBasePerson +from loops.organize.util import getPrincipalFolder, authPluginId _ = MessageFactory('zope') @@ -50,7 +53,8 @@ class UserId(schema.TextLine): def _validate(self, userId): if not userId: return - auth = component.getUtility(IAuthentication, context=self.context) + context = removeSecurityProxy(self.context).context + auth = component.getUtility(IAuthentication, context=context) try: principal = auth.getPrincipal(userId) except PrincipalLookupError: @@ -58,7 +62,7 @@ class UserId(schema.TextLine): mapping={'userId': userId})) pa = annotations(principal) person = pa.get(ANNOTATION_KEY, None) - if person is not None and person != self.context: + if person is not None and person != context: raiseValidationError( _(u'There is alread a person ($person) assigned to user $userId.', mapping=dict(person=zapi.getName(person), @@ -69,6 +73,10 @@ class LoginName(schema.TextLine): def _validate(self, userId): super(LoginName, self)._validate(userId) + if userId in getPrincipalFolder(self.context): + raiseValidationError( + _(u'There is alread a user with ID $userId.', + mapping=dict(userId=userId))) class Password(schema.Password): diff --git a/organize/member.py b/organize/member.py index 5714a2f..7c3e9ed 100644 --- a/organize/member.py +++ b/organize/member.py @@ -39,6 +39,7 @@ from cybertools.typology.interfaces import IType from loops.interfaces import ILoops from loops.concept import Concept from loops.organize.interfaces import IMemberRegistrationManager +from loops.organize.util import getPrincipalFolder, authPluginId _ = MessageFactory('zope') @@ -48,40 +49,32 @@ class MemberRegistrationManager(object): implements(IMemberRegistrationManager) adapts(ILoops) - authPluginId = 'loops' - def __init__(self, context): self.context = context def register(self, userId, password, lastName, firstName=u'', **kw): # step 1: create an internal principal in the loops principal folder: - pau = zapi.getUtility(IAuthentication, context=self.context) - if not IPluggableAuthentication.providedBy(pau): - raise ValueError(u'There is no pluggable authentication ' - 'utility available.') - if not self.authPluginId in pau.authenticatorPlugins: - raise ValueError(u'There is no loops authenticator ' - 'plugin available.') - pFolder = component.queryUtility(IAuthenticatorPlugin, self.authPluginId, - context=pau) + pFolder = getPrincipalFolder(self.context) title = firstName and ' '.join((firstName, lastName)) or lastName # TODO: care for password encryption: principal = InternalPrincipal(userId, password, title) pFolder[userId] = principal # step 2: create a corresponding person concept: cm = self.context.getConceptManager() - id = userId + id = baseId = 'person.' + userId num = 0 while id in cm: num +=1 - id = userId + str(num) + id = baseId + str(num) person = cm[id] = Concept(title) # TODO: the name of the person type object must be kept flexible! + # So we have to search for a type concept that has IPerson as + # its typeInterface... person.conceptType = cm['person'] personAdapter = IType(person).typeInterface(person) personAdapter.firstName = firstName personAdapter.lastName = lastName - personAdapter.userId = '.'.join((self.authPluginId, userId)) + personAdapter.userId = '.'.join((authPluginId, userId)) notify(ObjectCreatedEvent(person)) notify(ObjectModifiedEvent(person)) return personAdapter diff --git a/organize/util.py b/organize/util.py new file mode 100644 index 0000000..e3890e3 --- /dev/null +++ b/organize/util.py @@ -0,0 +1,44 @@ +# +# Copyright (c) 2006 Helmut Merz helmutm@cy55.de +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +""" +Utilities for the loops.organize package. + +$Id$ +""" + +from zope.app import zapi +from zope import interface, component, schema +from zope.app.authentication.interfaces import IPluggableAuthentication +from zope.app.authentication.interfaces import IAuthenticatorPlugin +from zope.app.security.interfaces import IAuthentication + +authPluginId = 'loops' + + +def getPrincipalFolder(context=None): + pau = zapi.getUtility(IAuthentication, context=context) + if not IPluggableAuthentication.providedBy(pau): + raise ValueError(u'There is no pluggable authentication ' + 'utility available.') + if not authPluginId in pau.authenticatorPlugins: + raise ValueError(u'There is no loops authenticator ' + 'plugin available.') + return component.queryUtility(IAuthenticatorPlugin, authPluginId, + context=pau) +