2

我在数据库中有例如表​​:

News:
id | user_id | title | body

和 CRUD:

public function executeIndex(sfWebRequest $request)
public function executeNew(sfWebRequest $request)
public function executeShow(sfWebRequest $request)
public function executeCreate(sfWebRequest $request)
public function executeEdit(sfWebRequest $request)
public function executeUpdate(sfWebRequest $request)
public function executeDelete(sfWebRequest $request)
protected function processForm(sfWebRequest $request, sfForm $form)

确保这一点的最佳方法是什么?我希望 USER 只能编辑、更新删除自己的News。我可以做到这一点 - 获取当前 ID 用户并与来自新闻和下一个重定向的 user_id 进行比较。也许我可以用 preExecute 或 yaml 文件来做这个?

4

2 回答 2

4

I used to do such a thing.

I choose to extend User class (myUser.class.php in application lib directory) with method can($what, Doctrine_Record $with), also declared few types of update types, like: const UPDATE = 'update'; and others, in the same way.

After that in preExecute() I've retrieved the currently requested object, in your case - News object, and calling if (!$this->getUser()->can(myUser::UPDATE, $news)) { /* redirect or whatever */ }.

As you can see, it's very easy readable and maintanable.

This way you have all access logic in one, method - can(), where you can specify any logic you need.

Hope, that helps you.

For your example, can() method would be something like:

switch(get_class($with))
{
    case 'News':
        if ($with->getUserId() != $this->getProfile()->getId()) // Assuming that getProfile() gives me a User class which News record is referenced
        {
            switch ($what)
            {
                case self::UPDATE:
                    return false;
                case self::DELETE:
                    return false;
            }
        }
        else
        {
            return true; // The user is owner - he can do whatever he want.
        }
        break;
    default:
        return false; // or true, don't know what you need
}
于 2012-04-27T09:31:14.293 回答
0

我做了很多相同的事情。但我没有扩展 sfUser 类。我使用了 symfony 的过滤器链http://www.symfony-project.org/book/1_2/06-Inside-the-Controller-Layer#chapter_06_filters并编写了我自己的能够解析路由配置的 SecurityFilter。

我在 routing.yml 的特定路由中添加了一个选项

contact_list:
  url: /contacts/:usergroup
  param: { module: contacts, action: index }
    options: { securityManager: UsergroupListSecurityManager }

例如: securityFilter 现在使用 UsergroupListSecurityManager 的实例来确定是否允许显示页面。

所以我能够设置默认的“securityManager”并在特定路由上定义任何特定的“securityManagers”——我还能够在不同的路由和其他上下文中重用一些“securityManager”(创建上下文菜单或工具栏)。

于 2012-04-30T11:41:29.867 回答