Август
Sub-archives
2010-08-22
Маскировка под другого пользователя в Zope 3 представлении браузера
Как и у Josh Johnson, автора статьи, чей вольный перевод я привожу здесь, у меня тоже была необходимость выполнять кое-какие действия от пользователя с ролью Anonymous, так, чтобы при этом не возникала ошибка авторизации пользователя.
Возьмем, например, задачу добавления анонимными пользователеми контента в папку. Они заполняют форму, которая проходит валидацию и создается новый объект. Звучит просто. Однако, на практике это не так :)
В Zope 2 есть Proxy Roles для скриптов, однако если ваша форма создана в zope3 стиле в виде представления браузера, для вас это не вариант.
В решении этой задачи может помочь модуль AccessControl, который входит в состав Zope 3.
Код может выглядеть как-то так:
from AccessControl.SecurityManagement import newSecurityManager, getSecurityManager, setSecurityManager
from Products.CMFCore.utils import getToolByName
...
class MyViewClass(SomeBaseViewClass):
# without going into detail here, assume that __init__ is passed a context and request object
# that are set as instance properties.
def someProcessorMethod(self):
# I've created a folder called "Special Folder" at the root of my Plone site.
portal = getToolByName(self.context, 'portal_url').getPortalObject()
owner = portal['special-folder'].getWrappedOwner()
# stash the existing security manager so we can restore it
old_security_manager = getSecurityManager()
# create a new context, as the owner of the folder
newSecurityManager(self.request, user)
try:
# make the content
portal['special-folder'].invokeFactory('Document',
'anonymous-content-ftw',
title='Anonymous Content FTW!')
except:
# we want to ensure that setSecurityManager gets called
# in reality you should do more here!
pass
# restore the original context
setSecurityManager(old_security_manager)
Вот и все, что нужно сделать. Одно из преимуществ такого подхода это то, что владелец папки может измениться, а код все равно будет работать.
При использовании этого кода нужно быть особенно осторожным с тем, где его позволено вызывать. Например, если представление может применяться везде (в атрибуте for в директиве регистрации представления стоит *), то можно представить какой беспорядок может натворить анонимный пользователь на вашем сайте.
Кроме того, весь код, выполняющийся от имени владельца папки, необходимо заключить в блок try catch, для того, чтобы быть уверенным, что если даже в процессе его выполнения произойдет ошибка, менеджер безопасности восстановится в свое прежнее состояние.

