Dazu wird der UserFolder durch das Produkt SimpleUserFolder ersetzt. Damit lassen sich leicht eigene Benutzerquellen und Rollen definieren. Um eine eigene Benutzerquelle einzurichten, muss im Tabulator "Zugriff" der Typ auf Benutzerdefiniert eingestellt werden.

Im Folgenden wird am Beispiel des mitgelieferten Beispiels der Aufbau einer einfachen eigenen Benutzerverwaltung Schritt für Schritt beschrieben. Die unten beschriebenen Methoden müssen entweder im Simple User Folder Objekt selbst oder einem Objekt, von dem aus der Simple User Folder sie akquirieren kann, angelegt werden.

Benutzerquelle (userSource)

Eine Benutzerquelle stellt der Benutzerverwaltung Informationen (Kennung, Passwort, Rollen) über alle Nutzer zur Verfügung. Um eine eigene Benutzerquelle zu erstellen, legen Sie eine DTML-Methode userSource an.

<!-- BO userSource (DTML Method) -->

<dtml-return "[
  {'name':'admin1','password':'zms'},
  {'name':'editor1','password':'zms'},
  {'name':'editor2','password':'zms'},
  {'name':'author1','password':'zms'},
  {'name':'author2','password':'zms'},
  {'name':'author3','password':'zms'},
  {'name':'author4','password':'zms'},
  {'name':'author5','password':'zms'},
  {'name':'author6','password':'zms'},
]">

<!-- EO userSource (DTML Method) -->

Benutzer einfügen (addUser)

Das Script(Python)-Objekt addUser definiert, wie Benutzer einem ZMS-Objekt zugewiesen werden. Im Beispiel wird für jeden Benutzer ein DTML-Dokument angelegt.

## Script (Python) "addUser"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=name, password, roles
##title=
##
container.manage_addDTMLDocument(id=name,title='')
user = getattr(context,name)
# user.manage_addProperty('password',password,'string')
user.manage_addProperty('roles',roles,'lines')
return 'done'

Benutzer ändern (editUser)

Das Script(Python)-Objekt editUser definiert, wie die Benutzereigenschaften geändert werden. Im Beispiel können nur die Rollen eines Benutzers als Eigenschaft des zugehörigen DTML Dokuments verändert werden. Alle weiteren Eigenschaften werden von der externen Benutzerquelle bereitgestellt.

## Script (Python) "editUser"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=name, password, roles
##title=
##
user = getattr(container,name)
# user.manage_changeProperties(password=password)
user.manage_changeProperties(roles=roles)
return 'done'

Benutzer löschen (deleteUser)

Das Script(Python)-Objekt deleteUser implementiert das Entfernen einer Benutzerzuweisung. Im Beispiel wird das dem Benutzer entsprechende DTML Dokument gelöscht.

## Script (Python) "deleteUser"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=name
##title=
##
container.manage_delObjects(ids=[name])
return 'done'

Namen aller Benutzer (getUserNames)

Die Namen bzw. IDs aller einem ZMS-Objekt zugewiesenen Benutzer erhält man über das Script(Python)-Objekt getUserNames.

## Script (Python) "getUserNames"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=
##title=
##
return container.objectIds(['DTML Document'])

Eigenschaften eines Benutzers (getUserDetails)

Die Eigenschaften eines einem ZMS-Objekt zugewiesenen Benutzers erhält man, indem man den Benutzernamen bzw. die -ID dem Script(Python)-Objekt getUserDetails als Parameter übergibt. Man erhält ein Dictionary mit allen zur Verfügung stehenden Eigenschaften.
getUserDetails muss immer zuletzt und unter anderem Namen hinzugefügt werden. Fügen Sie dazu ein Script(Python)-Objekt getUserDetails2 ein und benennen Sie dies anschliessend in getUserDetails um.

## Script (Python) "getUserDetails"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=name
##title=
##
userSource = []
dtml_method = getattr(container,'userSource',None)
if dtml_method is not None:
  userSource = dtml_method()

user = getattr(container,name,None)
if user is not None:
  for userSourceItem in userSource:
    if userSourceItem['name'] == name:
      return {
        'password' : userSourceItem['password'],
        'roles'    : user.getProperty('roles'),
        }

return None

Management Interface

Das ZMS Management Interface zum Bearbeiten der Benutzer kann auf die Bedürfnisse der eigenen Benutzerverwaltung angepasst werden. Dazu wird die DTML Methode manage_SimpleUserFolder eingebunden. Diese muss selbständig die Anzeige sowie das Bearbeiten (Einfügen, Ändern, Löschen) der Nutzer übernehmen.

<!-- BO manage_SimpleUserFolder (DTML Method) -->

<dtml-let user_list="_['userSource']">

<!---------// BO Roles //---------->
<dtml-call "REQUEST.set('tmp',[])">
<dtml-in "valid_roles()">
 <dtml-let role="_['sequence-item']"
           name="_.string.upper('ROLE_%s'%_.str(role))"
           display="getLangStr(name,manage_lang)">
  <dtml-if "(AUTHENTICATED_USER.has_permission('ZMS Administrator',getSelf()) 
      and not role in ['Anonymous','Authenticated','Owner']) or
            (AUTHENTICATED_USER.has_permission('ZMS Editor',getSelf()) 
      and role in ['ZMSEditor','ZMSAuthor','ZMSSubscriber'])">
   <dtml-if "display!=name">
    <dtml-call "tmp.append((display,role))">
   </dtml-if>
  </dtml-if>
 </dtml-let>
</dtml-in>
<dtml-call "tmp.sort()">
<dtml-call "REQUEST.set('select_roles',[])">
<dtml-in tmp>
  <dtml-call "select_roles.append([_['sequence-item'],_['sequence-key']])">
</dtml-in>
<!---------// EO Roles //---------->

<!---------// BO Add/delete users //--------->
<dtml-if btn>
 <dtml-if "btn==getLangStr('BTN_ADD',manage_lang)">
  <dtml-with "getUserFolder()">
   <dtml-in user_list mapping>
    <dtml-if "name==new_name">
     <dtml-call "addUser(new_name,password,new_roles)">
    </dtml-if>
   </dtml-in>
  </dtml-with>
  <div class="system-msg">
   <dtml-var "getLangStr('MSG_INSERTED',manage_lang)
     %('%s <i>%s</i>'%(getLangStr('ATTR_USER',manage_lang),new_name))">
   (<dtml-var "getLangFmtDate(ZopeTime(),manage_lang)">)
  </div>
 <dtml-elif "btn==getLangStr('BTN_DELETE',manage_lang)">
  <dtml-with "getUserFolder()">
   <dtml-in "REQUEST.get('names',[])">
    <dtml-call "deleteUser(_['sequence-item'])">
   </dtml-in>   
  </dtml-with>
  <div class="system-msg">
   <dtml-var "getLangStr('MSG_DELETED',manage_lang)
     %_.len(REQUEST.get('names',[]))">
   (<dtml-var "getLangFmtDate(ZopeTime(),manage_lang)">)
  </div>
 </dtml-if>
 <dtml-call "synchronizePublicAccess()">
</dtml-if>
<!---------// EO Add/delete users //--------->

<!------// BO Insert user form //------>
<dtml-call "REQUEST.set('user_names',getUserNames())">
<table cellspacing="1" cellpadding="0" border="0" 
  class="cmsBgColorStrong1">
 <tr>
  <td class="form-small" colspan="2">
   <b>
    <dtml-var "getLangStr('CAPTION_INSERT',manage_lang)
      %getLangStr('ATTR_USER',manage_lang)">
   </b>
  </td>
 </tr>
 <tr valign="middle" class="cmsBgColorLight0">
  <td class="form-small">
   <b>
    <dtml-var "getLangStr('ATTR_NAME',manage_lang)">
   </b>
  </td>
  <td class="form-small">
   <select class="form-small" name="new_name">
    <dtml-in user_list mapping>
     <dtml-unless "name in user_names">
      <option value="<dtml-var name>">
       <dtml-var name>
      </option>
     </dtml-unless>
    </dtml-in>
   </select>
  </td>
 </tr>
 <tr valign="middle" class="cmsBgColorLight0">
  <td class="form-small">
   <b><dtml-var "getLangStr('ATTR_ROLES',manage_lang)"></b>
  </td>
  <td class="form-small">
   <select class="form-small" name="new_roles:list" multiple="multiple">
    <dtml-in select_roles>
     <option value="<dtml-var "_['sequence-item'][0]">">
      <dtml-var "_['sequence-item'][1]">
     </option>
    </dtml-in>
   </select>
  </td>
 </tr>
 <tr valign="middle" class="cmsBgColorLight0">
  <td></td>
  <td class="form-small">
   <input class="form-small" type="submit" name="btn" 
     value="<dtml-var "getLangStr('BTN_ADD',manage_lang)">">
  </td>
 </tr>
</table>
<br>
<!------// EO Insert user form //------>

<!------// BO Display users //------>
<dtml-if user_names>
<table cellspacing="1" cellpadding="0" border="0"
  class="cmsBgColorStrong1">
 <tr valign="middle">
  <td class="form-small" colspan="2">
   <b>
    <dtml-var "_.len(getUserNames())"> 
    <dtml-var "getLangStr('ATTR_USER',manage_lang)">
   </b>
  </td>
  </td>
 </tr>
 <dtml-in user_names>
 <tr valign="middle" 
   <dtml-if sequence-odd>class="cmsBgColorLight0"
   <dtml-else>class="cmsBgColorMedium0"</dtml-if>>
  <td class="form-small" width="1%">
   <input type="checkbox" name="names:list" value="<dtml-var sequence-item>">
  </td>
  <td class="form-small" width="83%">
   <dtml-var sequence-item>
   <dtml-let user_details="getUserDetails(_['sequence-item'])">
    <dtml-if user_details>
     <i>(
      <dtml-in "user_details.get('roles','')">
       <dtml-var sequence-item>
       <dtml-unless sequence-end>, </dtml-unless>
      </dtml-in>)
     </i>
    </dtml-if>
   </dtml-let>
  </td>
 </tr>
 <dtml-if sequence-end>
 <tr>
  <td class="form-small" colspan="2">
   <input class="form-small" type="submit" name="btn" 
     value="<dtml-var "getLangStr('BTN_DELETE',manage_lang)">">
  </td>
 </tr>
 </dtml-if>
 </dtml-in>
</table>
<br>
</dtml-if>
<!------// EO Display users //------>

</dtml-let>

<!-- EO manage_SimpleUserFolder (DTML Method) -->

Erstellt von: Dirk Nordmann , erstellt am:  27.06.2008 , zuletzt geändert: 16.05.2014