33. Haciendo nuestro paquete reusable

Esta paquete contiene algunos problemas.

  • Sin la configuración de permisos, los usuarios no pueden personalizar quién y cuándo los usuarios pueden votar.

  • Hacemos cosas, pero no provocamos eventos. Los eventos permiten que otros reaccionen.

Agregando permisos

Los permisos tienen una larga historia, hay dos tipos de permisos.

En Zope2, un permiso era sólo una cadena.

En ZTK, un permiso es un objeto que se obtiene registrado como una Utilidad.

Debemos apoyar a ambos, en algunos casos tenemos que referenciar el permiso por su versión Zope2, en algunos por su versión ZTK.

Por suerte, hay una declaración ZCML para registrar un permiso de ambas maneras en un solo paso.

Ver también

El registro de configuración quería resolver un problema, pero ahora nos topamos con un problema que no se resolvió correctamente.

Nuestro permiso es una utilidad. Nuestras browser views declaran este permiso como un requisito para verlas.

Cuando nuestras browser views se registren, los permisos deben existir ya. Si intenta registrar los permisos después de las vistas, Zope no se iniciará porque no sabe acerca de los permisos.

Modificar el archivo configure.zcml, con el siguiente código ZCML:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<configure
  ...>

  <includeDependencies package="." />

  <permission
      id="starzel.votable_behavior.view_vote"
      title="starzel.votable_behavior: View Vote"
      />

  <permission
      id="starzel.votable_behavior.do_vote"
      title="starzel.votable_behavior: Do Vote"
      />

  <include package=".browser" />

  ...

</configure>

En algunos lugares tenemos que hacer referencia a las cadenas de permisos de Zope 2. Es la mejor práctica proporcionar una variable estática para esto.

Proporcionamos esto en el archivo __init__.py, con el siguiente código Python:

1
2
3
...
DoVote = 'starzel.votable_behavior: Do Vote'
ViewVote = 'starzel.votable_behavior: View Vote'

Usando nuestros permisos

Como puede ver, creamos dos permisos, uno para votar, uno para ver los votos.

Si uno no puede ver las votaciones, no necesita acceso al viewlet de votos.

Mientras estamos en ello, si uno no puede votar, no necesita acceso a la helper view para presentar realmente un voto.

Podemos agregar esta restricción al archivo browser/configure.zcml, con el siguiente código ZCML:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<configure
  xmlns="http://namespaces.zope.org/zope"
  xmlns:browser="http://namespaces.zope.org/browser"
  i18n_domain="starzel.votable_behavior">

  <browser:viewlet
    name="voting"
    for="starzel.votable_behavior.interfaces.IVotable"
    manager="plone.app.layout.viewlets.interfaces.IBelowContentTitle"
    template="templates/voting_viewlet.pt"
    layer="..interfaces.IVotableLayer"
    class=".viewlets.Vote"
    permission="starzel.votable_behavior.view_vote"
    />

  <browser:page
    name="vote"
    for="starzel.votable_behavior.interfaces.IVotable"
    layer="..interfaces.IVotableLayer"
    class=".vote.Vote"
    permission="starzel.votable_behavior.do_vote"
    />

  ...

</configure>

Estamos configurando componentes, por lo que usamos el nombre de componente del permiso, que es el id parte de la declaración que añadimos anteriormente.

Ver también

Entonces, ¿qué sucede, si no protegemos la browser view para votar?

La persona podría votar, mediante la elaboración manual de la URL. Las Browser Views ejecutar código sin ninguna restricción, es su trabajo tener cuidado de la seguridad.

Pero... si una persona no tiene acceso al objeto en absoluto, tal vez porque el sitio está configurado para que los usuarios anónimos no puedan acceder a objetos privados, los usuarios no autorizados no podrán enviar un voto.

Es decir, porque Zope comprueba los permisos de seguridad al intentar encontrar el objeto correcto. Si no puede encontrar el objeto debido a las restricciones de seguridad no se cumplen, ninguna vista mal, nunca ser llamado, ya que habría sido el siguiente paso.

Ahora protegemos nuestras views y viewlets. Todavía mostramos la opción de votar.

Debemos agregar una condición en nuestra plantilla de página, y debemos proporcionar la información de la condición en nuestra clase viewlet.

Mueva al archivo browser/viewlets.py, con el siguiente código Python:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
...

from starzel.votable_behavior import DoVote


class Vote(base.ViewletBase):

     ...
     can_vote = None

    def update(self):

        ...

        if self.is_manager is None:
            membership_tool = getToolByName(self.context, 'portal_membership')
            self.is_manager = membership_tool.checkPermission(
                ViewManagementScreens, self.context)
            self.can_vote = membership_tool.checkPermission(
                DoVote, self.context)

...

Y la plantilla en el archivo browser/templates/voting_viewlet.pt, con el siguiente código ZPT:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<tal:snippet omit-tag="">
  <div class="voting">

    ...

    <div id="notyetvoted" class="voting_option"
            tal:condition="view/can_vote">
      What do you think of this talk?
      <div class="votes"><span id="voting_plus">+1</span> <span id="voting_neutral">0</span> <span id="voting_negative">-1</span>
      </div>
    </div>
    <div id="no_ratings" tal:condition="not: view/has_votes">
      This talk has not been voted yet.<span tal:omit-tag="" tal:condition="view/can_vote"> Be the first!</span>
    </div>

  ...

  </div>

...

</tal:snippet>

A veces se producen errores sutiles debido a los cambios, en este caso, me di cuenta de que sólo debería animar a la gente a votar, ¡si a ellos se les permite votar!

Proporcionar valores por defecto

¿Ya terminamos?, ¿Quién puede votar ahora?

Tenemos que decirle a alguien.

En el ZTK, un permiso es un objeto que se obtiene registrado como una Utilidad.

La configuración persistente se gestiona en otro archivo: profiles/default/rolemap.xml, con el siguiente código XML:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<?xml version="1.0"?>
<rolemap>
  <permissions>
    <permission name="starzel.votable_behavior: View Vote" acquire="True">
      <role name="Anonymous"/>
    </permission>
    <permission name="starzel.votable_behavior: Do Vote" acquire="True">
      <role name="Anonymous"/>
    </permission>
  </permissions>
</rolemap>