sfContext :: getInstance () -> getUser () не работает в createQuery из валидатора - PullRequest
0 голосов
/ 29 июля 2011

Сейчас: решено - больше не воспроизводится

Для некоторых конкретных приложений безопасности у меня есть следующая функция createQuery для таблицы, т.е. вы можете получить доступ к записи таблицы, только если у вас есть учетные данные «Администратор» или вы являетесь пользователем, который хранится в отношении MembershipDelegate.

class OrganisationTable extends Doctrine_Table
function createQuery($alias = ''){

    if (!$alias){
        $alias = 'o';
    }

    $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->hasCredential('Administrator')){
        //all good

    }else{


        $userId = $user->getAttribute('userId');
        print "<!--testaa ".print_r($user->getCredentials(),1).'-->';
        $query->
        leftJoin("$alias.MembershipDelegate mdelsec")->
        addWhere ("mdelsec.joomla_user_id=$userId");
    }

    return $query;
}

Кажется, это работает нормально на всех уровнях, однако есть валидатор выбора, для которого объект $ user, кажется, возвращается пустым

    /**
     * Person form base class.
     *
     */
     ...
    abstract class BasePersonForm extends BaseFormDoctrine
    {
      public function setup()
      {
        $this->setWidgets(array(

    ...
          'organisation_id'                          => new sfWidgetFormDoctrineChoice(array('model' => $this->getRelatedModelName('Organisation'), 'add_empty' => true)),


    class PersonForm extends BasePersonForm{

        public function configure(){

            $this->widgetSchema['organisation_id']->setOption('renderer_class', 'sfWidgetFormDoctrineJQueryAutocompleter');
            $this->widgetSchema['organisation_id']->setOption('renderer_options', array(
            'model' => 'Organisation',
            'url' => NZGBCTools::makeUriJoomlaCompatible(
                    sfContext::getInstance()->getController()->genUrl('organisation/jsonList'))
            ));
            $this->validatorSchema['organisation_id']->setOption('required',false);

есть ли другой способ получить объект пользователя в модели?

Этот подход к защите на уровне строк может не соответствовать MVC, но является IMO более безопасным и более эффективным, чем реализация тех же концепций безопасности в действиях:

  • Может использоваться с готовыми модулями администратора-генератора.
  • Гораздо сложнее забыть реализовать его где-нибудь
  • Временами может не потребоваться никаких учетных данных, только доступ с правами супер администратора

Ответы [ 3 ]

0 голосов
/ 29 июля 2011

Я думаю, что вы что-то здесь упустили, вы довольно много перепутали слои MVC.Мое предложение состоит в том, чтобы сделать Модель независимой от Контроллера (делегировать Контроллеру специфичные для контекста ситуации), и Контроллер должен также выполнить проверку (должно быть действие, которое получает запрос, связывает форму и проверяет ее.Есть место, где вы должны определить, что именно является контекстным спецификом).Вот что я хотел бы сделать:

  1. В классе OrganisationTable должно быть 2 метода: createQueryForAdministrator и createQueryForMembershipDelegate.Каждый из них делает то, что должен, и теперь вы должны изменить контроллер (действие, которое его обрабатывает) и сделать что-то вроде:

    public function executeAction(sfWebRequest $request)
    {
      if ($this->getUser()->hasCredential('administrator'))
      {
        //call the administrator method
       } else {
        //call the other method
       }
     }
    
  2. Действие, которое создает экземпляр формы, должнотакже проверьте учетные данные пользователя и сделайте что-то вроде:

    If ($user->hasCredential("administrator"))
    {
       sfContext::getInstance()->getConfiguration()->loadHelper("Url");
       $form->getValidator("organization_id")->setOption("url",url_for("@action"));
       [..]
    } else {
       [..]
    }
    

Проверьте справочную ссылку url , вы можете думать как загружать помощников в действия и т. д., и вы можетеТакже создайте своих собственных помощников тоже.Надеюсь, это поможет!

РЕДАКТИРОВАНИЕ: Проверьте этот пост о классе sfContext и альтернативах

0 голосов
/ 03 августа 2011

Теперь кажется, что этот вопрос был случайностью, так как я не могу воспроизвести проблему после исправления других проблем, связанных с аутентификацией пользователя.

0 голосов
/ 29 июля 2011

Я не знаю другого способа получить пользователя сеанса в моделях (я не думаю, что он есть), но если вы можете, вы должны передать объект пользователя моделям.

...