首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于symfony2用户升级的symfony1约束模型

基于symfony2用户升级的symfony1约束模型
EN

Stack Overflow用户
提问于 2014-12-01 08:13:02
回答 1查看 35关注 0票数 0

我正在构建一个多租户应用程序。在Symfony1中,我将通过访问用户详细信息和扩展createQuery函数来限制对数据的访问:

代码语言:javascript
复制
class PersonTable extends Doctrine_Table{    
    public function createQuery($alias = '')
    {

        $query = parent::createQuery($alias);

        try {
            $user = sfContext::getInstance()->getUser();
        }catch(Exception $e){
            if ($e->getMessage() == 'The "default" context does not exist.'){
                return $query;
            }else{
                throw $e;
            }
        }
        if ($user->hasGroup('Team1')){
            //all good

        }else if ($user->hasGroup('Team2')){

            $user_id = $user->getGuardUser()->getStaff()->getId();
            $alias = $query->getRootAlias();
            $time = date('Y-m-d H:i:s',time());
            $query->andWhere("$alias.type='type1' and pe.assigned_psw_id");
        }
        $query->orderBy('name asc');

        return $query;
    }
}

我知道通过sfContext在sf1中访问用户对象有一些缺点,但这种方法似乎优于其他方法,因为您不能“忘记”保护控制器以防止错误的用户访问。

我如何在Symfony2中实现同样的目标?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-07-21 09:04:35

我用以下方法解决了这个问题。

标准化控制器之间获取EntityRepository的方式:

代码语言:javascript
复制
public function getUserRestrictedRepository($entity, $em = null )
{
    $securityContext = $this->get( 'security.context' );
    if (!$em){
        $em = $this->getDoctrine()->getManager();
    }
    return $em
        ->getRepository( 'MyBundle:' . $entity )
        ->setSecurityContext( $securityContext );
}

添加一个特性以提供具有注入安全性查询的查询:

代码语言:javascript
复制
trait UserRestrictedEntityRepository {

    private $securityContext;

    /**
     * @return mixed
     */
    public function getSecurityContext()
    {
        return $this->securityContext;
    }

    /**
     * @param mixed $securityContext
     */
    public function setSecurityContext($securityContext)
    {
        $this->securityContext = $securityContext;
        return $this;
    }


    /**
     * @return mixed
     */
    public function getUser()
    {
        return $this->getSecurityContext()->getToken()->getUser();
    }


    /**
     * @return mixed
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @param mixed $name
     */
    public function setName($name)
    {
        $this->name = $name;
    }


    function secureQueryWithUser($alias, $qb)
    {
        $qb->where("1=0");
    }


    function appendOrderBy($qb, $orderBy)
    {
        $first = true;
        foreach ($orderBy as $field => $dir) {
            if (!$dir) $dir = 'asc';
            if ($first) {
                $qb->orderBy('c.' . $field, $dir);
                $first = false;
            }else{
                $qb->addOrderBy('c.' . $field, $dir);
            }
        }
    }


    public function createUnrestrictedQueryBuilder($alias)
    {
        return parent::createQueryBuilder($alias);
    }

    /**
     * Creates a new QueryBuilder instance that is prepopulated for this entity name.
     *
     * @param string $alias
     *
     * @return QueryBuilder
     */
    public function createQueryBuilder($alias, $indexBy=NULL)
    {
        if ($this->getUser()) {

            $qb = $this->_em->createQueryBuilder()
                ->select($alias)
                ->from($this->_entityName, $alias);
            if (isset($this->defaultOrder) && $this->defaultOrder){
                $this->appendOrderBy($qb, $this->defaultOrder);
            }
            if ($this->getUser()->isSuperAdmin()){
                return $qb;
            }else{
                return $this->secureQueryWithUser($alias, $qb);
            }

        }else{
            throw new Exception('Run setUser() before querying ' . $this->getName() .' model.');
        }
    }


    /**
     * Finds all entities in the repository.
     *
     * @return array The entities.
     */
    public function findAll()
    {
        return $this->findBy(array());
    }


    /**
     * Finds entities by a set of criteria.
     *
     * @param array      $criteria
     * @param array|null $orderBy
     * @param int|null   $limit
     * @param int|null   $offset
     *
     * @return array The objects.
     */
    public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
    {
        $qb = $this->createQueryBuilder('c');

        foreach ($criteria as $fkey => $fval){
            $qb->andWhere($fkey.' = :'.$fval);
        }
        if ($limit){
            $qb->setMaxResults($limit);
        }
        if ($offset){
            $qb->setFirstResult($offset);
        }
        $query = $qb->getQuery();

        return $query->getResult();
    }
}

在EnityRepository中实现基于用户访问的查询添加

代码语言:javascript
复制
class FarmerRepository extends EntityRepository
{
    use UserRestrictedEntityRepository;

    private $name = 'Farmer';

    private $defaultOrder = array('name' => 'asc');


    function secureQueryWithUser($alias, $qb)
    {
        if ($this->getSecurityContext()->isGranted( 'ROLE_CLINIC_ADMIN' )) {
            return $qb
                ->innerJoin("$alias.vet", 'v')
                ->innerJoin("v.clinic", "cl")
                ->innerJoin("cl.VetsOfClinic", "vc")
                ->andWhere('vc.user_id= :userid')
                ->setParameter('userid', $this->getUser()->getId());
        }else if ($this->getSecurityContext()->isGranted( 'ROLE_VET' )){
            return $qb
                ->innerJoin("$alias.vet", 'v')
                ->andWhere('v.user_id= :userid')
                ->setParameter('userid', $this->getUser()->getId());
        }else{
            return $qb
                ->where("$alias.user_id= :userid")
                ->setParameter('userid', $this->getUser()->getId());
        }
    }

}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27224190

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档