<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://prendreuncafe.com/blog/feed/rss2/xslt" ?><rss version="2.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>Prendre un Café - Tag - security</title>
  <link>http://prendreuncafe.com/blog/</link>
  <atom:link href="http://prendreuncafe.com/blog/feed/tag/security/rss2" rel="self" type="application/rss+xml"/>
  <description></description>
  <language>fr</language>
  <pubDate>Tue, 01 Feb 2011 14:49:24 +0100</pubDate>
  <copyright>Contenus sous licence Creative Commons BY-SA</copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>User Dependent Forms with Symfony</title>
    <link>http://prendreuncafe.com/blog/post/2010/02/17/User-Dependant-Forms-with-Symfony</link>
    <guid isPermaLink="false">urn:md5:afa96fedd9e7bc61404cdf6e257005b0</guid>
    <pubDate>Wed, 17 Feb 2010 09:04:00 +0100</pubDate>
    <dc:creator>NiKo</dc:creator>
        <category>Dev</category>
        <category>best practices</category><category>credentials</category><category>forms</category><category>php</category><category>security</category><category>session</category><category>symfony</category>    
    <description>    &lt;p&gt;While sadly not being at &lt;a href=&quot;http://www.symfony-live.com/&quot;&gt;Symfony Live 2010&lt;/a&gt; with pals, I&amp;#8217;m drowning my sorrow into tech tutorials writing.&lt;/p&gt;


&lt;p&gt;Sometimes you want to design forms and contextualize them regarding the current user session. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manage the display of some fields regarding the user authentication status and credentials;&lt;/li&gt;
&lt;li&gt;Filter some queries used to get the values available in a &lt;code&gt;&amp;lt;select/&amp;gt;&lt;/code&gt; tag;&lt;/li&gt;
&lt;li&gt;Allow multiple steps form validation with step state persistence (wizzard);&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So how can we achieve this without using an evilish &lt;code&gt;sfContext::getInstance()-&amp;gt;getUser()&lt;/code&gt; call in the &lt;code&gt;configure()&lt;/code&gt; method of the form?&lt;/p&gt;


&lt;p&gt;Symfony &lt;del&gt;1.2&lt;/del&gt; &lt;strong&gt;1.3 and 1.4&lt;/strong&gt; introduced the generation of a project-wide &lt;code&gt;BaseForm&lt;/code&gt; class we can use here to setup some convenient methods to allow user setters and getters:&lt;/p&gt;

&lt;pre&gt; php
&amp;lt;?php
class BaseForm extends sfFormSymfony
{
  static protected $user = null;

  static public function getUser()
  { 
    return self::$user;
  }

  static public function getValidUser()
  {
    if (!self::$user instanceof sfBasicSecurityUser)
    {
      throw new RuntimeException('No valid user instance available');
    }
    
    return self::$user;
  }

  static public function setUser(sfBasicSecurityUser $user)
  {
    self::$user = $user;
  }
}
&lt;/pre&gt;


&lt;p&gt;Okay, we now can set a user instance as a static property of all available forms within the project, nice. Wait, how the hell will we set the instance, and when?&lt;/p&gt;


&lt;p&gt;Symfony dispatch a very useful &lt;code&gt;context.load_factories&lt;/code&gt; event when all the factories - including the &lt;code&gt;user&lt;/code&gt; one - are instanciated and available in the context. So we can listen to this event and set the user instance to the forms when it&amp;#8217;s ready. We&amp;#8217;ll do this in the &lt;code&gt;ProjectConfiguration.class.php&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt; php
&amp;lt;?php
class ProjectConfiguration extends sfProjectConfiguration
{
  public function setup()
  {
    // ...
    
    $this-&amp;gt;dispatcher-&amp;gt;connect('context.load_factories', array($this, 'listenToLoadFactoriesEvent'));
  }

  public function listenToLoadFactoriesEvent(sfEvent $event)
  {
    BaseForm::setUser($event-&amp;gt;getSubject()-&amp;gt;getUser());
  }
}
&lt;/pre&gt;


&lt;p&gt;So now we&amp;#8217;ve set a static user instance in every form at project configuration time, we can use it in any form.&lt;/p&gt;


&lt;p&gt;For example, imagine a form where only authenticated users having an &lt;code&gt;admin&lt;/code&gt; credential can see, fill and submit an hypothetic &lt;code&gt;is_published&lt;/code&gt; field:&lt;/p&gt;

&lt;pre&gt; php
class myForm extends BaseForm
{
  public function configure()
  {
    // will throw an exception if no user is available
    $user = self::getValidUser();
    
    $this-&amp;gt;setWidgets(array(
      'title' =&amp;gt; new sfWidgetFormInputText(),
      'body' =&amp;gt; new sfWidgetFormTextarea(),
    ));
    
    $this-&amp;gt;setValidators(array(
      'title' =&amp;gt; new sfValidatorString(array('min_length' =&amp;gt; 5)),
      'body' =&amp;gt; new sfValidatorString(array('min_length' =&amp;gt; 20)),
    ));
    
    if ($user-&amp;gt;isAuthenticated() &amp;amp;&amp;amp; $user-&amp;gt;hasCredential('admin'))
    {
      $this-&amp;gt;widgetSchema['is_published'] = new sfWidgetFormInputCheckbox();
      $this-&amp;gt;validatorSchema['is_published'] = new sfValidatorBoolean(array(
        'required' =&amp;gt; false,
      ));
    }
    
    // ...
  }
}
&lt;/pre&gt;


&lt;p&gt;Here a basic user won&amp;#8217;t see and won&amp;#8217;t be able to submit any value for the &lt;code&gt;is_published&lt;/code&gt; field. Note that all those changes won&amp;#8217;t ever affect the controllers or the model, and the forms will still be easily testable because the forms and the user instance are not tightly coupled.&lt;/p&gt;


&lt;p&gt;As a side note, you can also use the form options to eventually pass a user instance and fallback on the static instance in case it&amp;#8217;s not available:&lt;/p&gt;

&lt;pre&gt; php
class myForm extends BaseForm
{
  public function configure()
  {
    // will throw an exception if no user is available
    $user = $this-&amp;gt;getOption('user', self::getValidUser());
    
    // ...
  }
}
&lt;/pre&gt;


&lt;p&gt;In a controller, you would use it this way:&lt;/p&gt;

&lt;pre&gt; php
&amp;lt;?php 
class fooActions extends sfActions
{
  public function executeBar(sfWebRequest $request)
  {
    $this-&amp;gt;form = new myForm(array('user' =&amp;gt; $this-&amp;gt;getUser()));
    
    // ...
  }
}
&lt;/pre&gt;


&lt;p&gt;A typical unit test suite of the form would be:&lt;/p&gt;

&lt;pre&gt; php
$t = new lime_test(2, new lime_output_color());

$user = new sfBasicSecurityUser(new sfEventDispatcher(), new sfSessionTestStorage(array(
  'session_path' =&amp;gt; sys_get_temp_dir(),
)));

$form = new myForm(array('user' =&amp;gt; $user));
$t-&amp;gt;is(count($form-&amp;gt;getWidgetSchema(), 2, '-&amp;gt;configure() displays 2 fields when user is not authenticated'));
$user-&amp;gt;setAuthenticated(true);
$user-&amp;gt;addCredential('admin');
$t-&amp;gt;is(count($form-&amp;gt;getWidgetSchema(), 3, '-&amp;gt;configure() displays 3 fields when user is authenticated and is an admin'));
// ... I'll let you complete the suite by yourself
&lt;/pre&gt;


&lt;p&gt;Now imagine we want to filter the choices offered by a one to many relationship field of a Doctrine form regarding user credentials:&lt;/p&gt;

&lt;pre&gt; php
class ArticleForm extends BaseArticleForm
{
  public function configure()
  {
    // will throw an exception if no user is available
    $user = $this-&amp;gt;getOption('user', self::getValidUser());
    
    // ...
    
    // Category choices
    $categoryQuery = $this-&amp;gt;getUserCategoryQuery($user);
    $this-&amp;gt;widgetSchema['category_id'] = new sfWidgetFormDoctrineChoice(array(
      'model' =&amp;gt; 'Category',
      'query' =&amp;gt; $categoryQuery,
    ));
    $this-&amp;gt;validatorSchema['community_id'] = new sfValidatorDoctrineChoice(array(
      'model' =&amp;gt; 'Category',
      'query' =&amp;gt; $categoryQuery,
    ));
  }
  
  /**
   * Please note that this method would naturally better fit in the model, in the 
   * ArticleTable class; We put this here for conciseness
   */
  protected function getUserCategoryQuery(sfBasicSecurityUser $user)
  {
    $query = Doctrine:getTable('Category')-&amp;gt;createQuery('c');
    
    // If user is not an admin, only allow choice of published categories
    if (!$user-&amp;gt;hasCredential('admin'))
    {
      $query-&amp;gt;where('c.is_published = 1');
    }
    
    return $query;
  }
}
&lt;/pre&gt;


&lt;p&gt;There are many more cool things you can achieve by offering user session access to a form, while keeping all the stuff easy to test.&lt;/p&gt;


&lt;p&gt;As usual, if you have a better way, feel free to tell us about it in the comments.&lt;/p&gt;&lt;hr/&gt;&lt;p style=&quot;margin:.5em 0;padding:.5em;border:1px solid #333;background:#eee;color:#222&quot;&gt;&lt;small&gt;Ce billet intitulé &lt;a href=&quot;http://prendreuncafe.com/blog/post/2010/02/17/User-Dependant-Forms-with-Symfony&quot;&gt;User Dependent Forms with Symfony&lt;/a&gt; a été rédigé par &lt;a href=&quot;http://prendreuncafe.com/cv&quot;&gt;Nicolas Perriault&lt;/a&gt; et publié sur le blog &lt;a href=&quot;http://prendreuncafe.com/blog/&quot;&gt;Prendre un Café&lt;/a&gt; sous licence &lt;a href=&quot;http://creativecommons.org/licenses/by-nc-sa/2.5/&quot;&gt;Creative Commons BY-NC-SA&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Demander à restreindre les caractères utilisés dans les mots de passe est idiot</title>
    <link>http://prendreuncafe.com/blog/post/2008/06/04/Demander-a-restreindre-les-caracteres-utilises-dans-les-mots-de-passe-est-idiot</link>
    <guid isPermaLink="false">urn:md5:f0b1a6866f144db2f77ede15d40d6c37</guid>
    <pubDate>Wed, 04 Jun 2008 12:25:00 +0200</pubDate>
    <dc:creator>NiKo</dc:creator>
        <category>Divers</category>
        <category>bestpractices</category><category>ergonomie</category><category>password</category><category>security</category>    
    <description>    &lt;p&gt;Voulant créer un compte sur un nouveau service en ligne, j'ai eu la désagréable surprise d'obtenir ce message d'erreur au moment de la validation de mon mot de passe :&lt;/p&gt;


&lt;blockquote&gt;&lt;p&gt;Password may only contain alphanumeric characters&lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;Pour les anglophobes, on me demande de n'utiliser que des caractères alphanumériques pour mon mot de passe.&lt;/p&gt;


&lt;p&gt;Ce n'est pas la première fois que je tombe sur la mise en place de pareil procédé. Quel est l'intérêt d'imposer cette limitation ? Je pense que plus un mot de passe utilise une plage de caractères diversifiée, plus il est sécurisé. Je peux éventuellement imaginer les problèmes que pourraient poser l'utilisation de caractères codés sur deux octets, ou encore l'angoisse d'une faille XSS potentielle chez les plus paranos, mais de là à interdire purement et simplement les tirets, underscores, espaces&lt;sup&gt;[&lt;a href=&quot;http://prendreuncafe.com/blog/post/2008/06/04/Demander-a-restreindre-les-caracteres-utilises-dans-les-mots-de-passe-est-idiot#pnote-974-1&quot; id=&quot;rev-pnote-974-1&quot;&gt;1&lt;/a&gt;]&lt;/sup&gt;, je trouve ça tout simplement &lt;strong&gt;idiot à tomber par terre&lt;/strong&gt;.&lt;/p&gt;


&lt;p&gt;Voila, c'est dit.&lt;/p&gt;


&lt;p&gt;&lt;strong&gt;Edit :&lt;/strong&gt; &lt;a href=&quot;http://googleblog.blogspot.com/2008/06/does-your-password-pass-test.html&quot; hreflang=&quot;en&quot;&gt;Quelques astuces sur la sécurisation des mots de passe&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href=&quot;http://prendreuncafe.com/blog/post/2008/06/04/Demander-a-restreindre-les-caracteres-utilises-dans-les-mots-de-passe-est-idiot#rev-pnote-974-1&quot; id=&quot;pnote-974-1&quot;&gt;1&lt;/a&gt;] Alors que &lt;a href=&quot;http://www.baekdal.com/articles/usability/password-security-usability/&quot; hreflang=&quot;en&quot;&gt;l'utilisation de deux espaces dans un mot de passe est très sécurisante&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;hr/&gt;&lt;p style=&quot;margin:.5em 0;padding:.5em;border:1px solid #333;background:#eee;color:#222&quot;&gt;&lt;small&gt;Ce billet intitulé &lt;a href=&quot;http://prendreuncafe.com/blog/post/2008/06/04/Demander-a-restreindre-les-caracteres-utilises-dans-les-mots-de-passe-est-idiot&quot;&gt;Demander à restreindre les caractères utilisés dans les mots de passe est idiot&lt;/a&gt; a été rédigé par &lt;a href=&quot;http://prendreuncafe.com/cv&quot;&gt;Nicolas Perriault&lt;/a&gt; et publié sur le blog &lt;a href=&quot;http://prendreuncafe.com/blog/&quot;&gt;Prendre un Café&lt;/a&gt; sous licence &lt;a href=&quot;http://creativecommons.org/licenses/by-nc-sa/2.5/&quot;&gt;Creative Commons BY-NC-SA&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
</channel>
</rss>

