<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>usefulfor.com/ruby</title>
	<atom:link href="http://usefulfor.com/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://usefulfor.com/ruby</link>
	<description>ruby goodness for your daily needs</description>
	<pubDate>Thu, 13 Nov 2008 11:20:06 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>extjs ComboBox remote XML</title>
		<link>http://usefulfor.com/ruby/2008/11/12/extjs-combobox-remote-xml/</link>
		<comments>http://usefulfor.com/ruby/2008/11/12/extjs-combobox-remote-xml/#comments</comments>
		<pubDate>Tue, 11 Nov 2008 23:33:47 +0000</pubDate>
		<dc:creator>etd</dc:creator>
		
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://usefulfor.com/ruby/?p=72</guid>
		<description><![CDATA[The new release of dradis is going to use the ExtJS library for the web interface. ExtJS provides lots of JavaScript widgets useful to create complex GUI for web applications.
This is the first of a series of posts with small tips and tricks of ExtJS that will also address its integration with Ruby on Rails. [...]]]></description>
			<content:encoded><![CDATA[<p>The new release of <a href="http://dradis.sourceforge.net/">dradis</a> is going to use the <a href="http://extjs.com/products/extjs/">ExtJS</a> library for the web interface. ExtJS provides lots of JavaScript widgets useful to create complex GUI for web applications.</p>
<p>This is the first of a series of posts with small tips and tricks of ExtJS that will also address its integration with Ruby on Rails. </p>
<p>In this release we are going to create a ComboBox that loads its items from a remote location (potentially a rails REST endpoint).</p>
<p><span id="more-72"></span></p>
<p>I wanted to create this series when I started using ExtJS so it could be used as a step-by-step howto of ExtJS and rails, but as sometimes happens, I got carried away with the coding side of things leaving the post writing abandoned :(. That is the main reason why some core concepts of ExtJS development are not included here. The project site, documentation and samples can help with that. Here we are dealing with the real stuff, so lets get it on.</p>
<p>First the code: <a href="http://usefulfor.com/ruby/files/2008/11/extjs-comboxml.tar.bz2">extjs-comboxml.tar.bz2</a>. I have a local apache for debuging purposes and I uncompressed the ExtJS package in <code>/var/www/ext-2.2/</code>, then I created a <code>test</code> folder inside it. This code should work fine if you uncompress its contents in the test folder. If you have a different environment, adjust the locations of the <strong>script</strong> tags in the header of <code>combo.html</code>.</p>
<p>This is how it should look like:<br />
<img src="http://usefulfor.com/ruby/files/2008/11/extjs-comboxml.png" alt="" width="370" height="105" class="centered size-full wp-image-73" /><br />
So with ExtJS there are two ways of loading combo items from a remote location, it is a bit confusing because these two are called <strong>local</strong> and <strong>remote</strong> modes. The difference is that in <strong>local</strong> mode, the combo is relying on someone else to grab the information and in <strong>remote</strong> mode the combo itself will make the Ajax call.</p>
<p>No matter what mode we choose, we will need a data store for our items. Here is the code used in the example:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">var </span><span class="hl-identifier">categories</span><span class="hl-default"> = </span><span class="hl-reserved">new </span><span class="hl-identifier">Ext</span><span class="hl-default">.</span><span class="hl-identifier">data</span><span class="hl-default">.</span><span class="hl-identifier">Store</span><span class="hl-brackets">({
        </span><span class="hl-identifier">url</span><span class="hl-code">: </span><span class="hl-quotes">'</span><span class="hl-string">categories.xml</span><span class="hl-quotes">'</span><span class="hl-code">,
        </span><span class="hl-identifier">autoLoad</span><span class="hl-code">: </span><span class="hl-reserved">true</span><span class="hl-code">, </span><span class="hl-comment">// required for the combo that does not use Ajax
        </span><span class="hl-identifier">reader</span><span class="hl-code">: </span><span class="hl-reserved">new </span><span class="hl-identifier">Ext</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-code">.</span><span class="hl-identifier">XmlReader</span><span class="hl-brackets">(
                { </span><span class="hl-identifier">record</span><span class="hl-code">: </span><span class="hl-quotes">'</span><span class="hl-string">category</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-identifier">id</span><span class="hl-code">: </span><span class="hl-quotes">'</span><span class="hl-string">id</span><span class="hl-quotes">'</span><span class="hl-brackets">}</span><span class="hl-code">,
                </span><span class="hl-brackets">[ { </span><span class="hl-identifier">name</span><span class="hl-code">: </span><span class="hl-quotes">'</span><span class="hl-string">name</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-identifier">type</span><span class="hl-code">: </span><span class="hl-quotes">'</span><span class="hl-string">string</span><span class="hl-quotes">' </span><span class="hl-brackets">} ]
              )</span><span class="hl-code">,
        </span><span class="hl-identifier">listeners</span><span class="hl-code">: </span><span class="hl-brackets">{
          </span><span class="hl-identifier">load</span><span class="hl-code">: </span><span class="hl-reserved">function</span><span class="hl-brackets">(</span><span class="hl-identifier">records</span><span class="hl-code">, </span><span class="hl-identifier">options</span><span class="hl-brackets">) {
            </span><span class="hl-identifier">console</span><span class="hl-code">.</span><span class="hl-identifier">log</span><span class="hl-brackets">( </span><span class="hl-quotes">'</span><span class="hl-string">loaded </span><span class="hl-quotes">'</span><span class="hl-code"> + </span><span class="hl-identifier">records</span><span class="hl-code">.</span><span class="hl-identifier">totalLength</span><span class="hl-code"> + </span><span class="hl-quotes">'</span><span class="hl-string"> records</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
          </span><span class="hl-brackets">}</span><span class="hl-code">,
          </span><span class="hl-identifier">loadexception</span><span class="hl-code">: </span><span class="hl-reserved">function</span><span class="hl-brackets">(</span><span class="hl-identifier">proxy</span><span class="hl-code">, </span><span class="hl-identifier">options</span><span class="hl-code">, </span><span class="hl-identifier">response</span><span class="hl-code">, </span><span class="hl-identifier">error</span><span class="hl-brackets">) {
            </span><span class="hl-identifier">console</span><span class="hl-code">.</span><span class="hl-identifier">log</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">error loading records from server:</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
            </span><span class="hl-identifier">console</span><span class="hl-code">.</span><span class="hl-identifier">log</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-special">\t</span><span class="hl-string">file: </span><span class="hl-quotes">&quot;</span><span class="hl-code">+</span><span class="hl-identifier">error</span><span class="hl-code">.</span><span class="hl-identifier">fileName</span><span class="hl-brackets">)</span><span class="hl-code">;
            </span><span class="hl-identifier">console</span><span class="hl-code">.</span><span class="hl-identifier">log</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-special">\t</span><span class="hl-string">line: </span><span class="hl-quotes">&quot;</span><span class="hl-code">+</span><span class="hl-identifier">error</span><span class="hl-code">.</span><span class="hl-identifier">lineNumber</span><span class="hl-brackets">)</span><span class="hl-code">;
          </span><span class="hl-brackets">}
        }
      })</span><span class="hl-default">;</span></pre></div></div>
<p>The listeners in the code above are just for debuging purposes and can be removed safely. The only interesting bit is the <strong>autoLoad</strong> option, but we will come back to that later. For now it is enough to say that the Store above will read an XML document with this structure:<br />
<code><br />
&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />
&lt;categories type="array"&gt;<br />
  &lt;category&gt;<br />
    &lt;id type="integer"&gt;1&lt;/id&gt;<br />
    &lt;name&gt;default category&lt;/name&gt;<br />
  &lt;/category&gt;<br />
  &lt;category&gt;<br />
    &lt;id type="integer"&gt;2&lt;/id&gt;<br />
    &lt;name&gt;security risk&lt;/name&gt;<br />
  &lt;/category&gt;<br />
&lt;/categories&gt;<br />
</code></p>
<p>The <code>autoLoad</code> config options determines if the data store will try to load the values from the provided url upon creation or if it will be necessary to call the <code>load()</code>. This is useful when we are working in <strong>local</strong> mode, let&#8217;s see the code for the first combo:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">var </span><span class="hl-identifier">comboLocal</span><span class="hl-default"> = </span><span class="hl-reserved">new </span><span class="hl-identifier">Ext</span><span class="hl-default">.</span><span class="hl-identifier">form</span><span class="hl-default">.</span><span class="hl-identifier">ComboBox</span><span class="hl-brackets">({
  </span><span class="hl-identifier">fieldLabel</span><span class="hl-code">: </span><span class="hl-quotes">'</span><span class="hl-string">Select a category</span><span class="hl-quotes">'</span><span class="hl-code">,
  </span><span class="hl-identifier">store</span><span class="hl-code">: </span><span class="hl-identifier">categories</span><span class="hl-code">,
  </span><span class="hl-identifier">mode</span><span class="hl-code">: </span><span class="hl-quotes">'</span><span class="hl-string">local</span><span class="hl-quotes">'</span><span class="hl-code">,
  </span><span class="hl-identifier">displayField</span><span class="hl-code">: </span><span class="hl-quotes">'</span><span class="hl-string">name</span><span class="hl-quotes">'</span><span class="hl-code">,
  </span><span class="hl-identifier">selectOnFocus</span><span class="hl-code">: </span><span class="hl-reserved">true</span><span class="hl-code">,
  </span><span class="hl-identifier">emptyText</span><span class="hl-code">: </span><span class="hl-quotes">'</span><span class="hl-string">No Ajax in the combo...</span><span class="hl-quotes">'
</span><span class="hl-brackets">})</span><span class="hl-default">;</span></pre></div></div>
<p>Above we specified <strong>local</strong> this means that options for this combo will be loaded from the <code>categories</code> store. The data store is expected to be populated already, this can be done either by specifying the <strong>autoLoad</strong> option as described above or by calling the <code>load()</code>.</p>
<p>If you rather have you combo performing the Ajax request, then the code you need to use is:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">var </span><span class="hl-identifier">comboRemote</span><span class="hl-default"> = </span><span class="hl-reserved">new </span><span class="hl-identifier">Ext</span><span class="hl-default">.</span><span class="hl-identifier">form</span><span class="hl-default">.</span><span class="hl-identifier">ComboBox</span><span class="hl-brackets">({
  </span><span class="hl-identifier">fieldLabel</span><span class="hl-code">: </span><span class="hl-quotes">'</span><span class="hl-string">Select a category</span><span class="hl-quotes">'</span><span class="hl-code">,
  </span><span class="hl-identifier">store</span><span class="hl-code">: </span><span class="hl-identifier">categories</span><span class="hl-code">,
  </span><span class="hl-identifier">displayField</span><span class="hl-code">: </span><span class="hl-quotes">'</span><span class="hl-string">name</span><span class="hl-quotes">'</span><span class="hl-code">,
  </span><span class="hl-identifier">triggerAction</span><span class="hl-code">: </span><span class="hl-quotes">'</span><span class="hl-string">all</span><span class="hl-quotes">'</span><span class="hl-code">,
  </span><span class="hl-identifier">selectOnFocus</span><span class="hl-code">: </span><span class="hl-reserved">true</span><span class="hl-code">,
  </span><span class="hl-identifier">emptyText</span><span class="hl-code">: </span><span class="hl-quotes">'</span><span class="hl-string">Options loaded using Ajax...</span><span class="hl-quotes">'
</span><span class="hl-brackets">})</span><span class="hl-default">;</span></pre></div></div>
<p>There is no need to include <code>mode: 'remote'</code> because is the default behaviour, here the trick is to include the <code>triggerAction: 'all'</code>, otherwise the Ajax request will never be executed.</p>
<p>So that was it, short and simple, stay tuned for the next one <img src='http://usefulfor.com/ruby/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /></p>
]]></content:encoded>
			<wfw:commentRss>http://usefulfor.com/ruby/2008/11/12/extjs-combobox-remote-xml/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Rails Conf 2008</title>
		<link>http://usefulfor.com/ruby/2008/09/11/rails-conf-2008/</link>
		<comments>http://usefulfor.com/ruby/2008/09/11/rails-conf-2008/#comments</comments>
		<pubDate>Thu, 11 Sep 2008 11:02:57 +0000</pubDate>
		<dc:creator>siebert</dc:creator>
		
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://usefulfor.com/ruby/?p=71</guid>
		<description><![CDATA[I attended Rails Conf 2008 in Berlin on the 3rd and 4th of September 2008. Following is a quick summary of the talks that I attended. There are loads interesting things going on in the Rails community. My opinion is very biased but I believe the Ruby on Rails community is setting the bar on [...]]]></description>
			<content:encoded><![CDATA[<p>I attended Rails Conf 2008 in Berlin on the 3rd and 4th of September 2008. Following is a quick summary of the talks that I attended. There are loads interesting things going on in the Rails community. My opinion is very biased but I believe the Ruby on Rails community is setting the bar on future web development. And I think this both the case for the techniques and approaches that is practised by these developers and equally the Ruby on Rails framework that is the result of this.<br />
<span id="more-71"></span></p>
<p><!--[if gte mso 9]&amp;gt;  Normal 0   false false false        MicrosoftInternetExplorer4  &amp;lt;![endif]--><!--[if gte mso 9]&amp;gt;   &amp;lt;![endif]--> <strong>Key note – David Heinemeier Hansson</strong></p>
<p>David is the creator of the Rails framework and obviously a bit of a celebrity. Interestingly enough I get the idea that he is not the highest contributor to the Rails code base – I appears to be Jeremy Kemper which is his colleague at 37signals (the company behind Ruby on Rails).</p>
<p>David delivered the keynote on Wednesday morning. The key note was on legacy code. Initially I thought – “What a boring subject” and then later I caught myself thinking – “Now you are talking a load of nonsense” and two thirds into it I was happy to admit – “Hey, you really have been thinking about this a lot”.</p>
<p>Maybe it is a sentiment that only or mostly developers can associate with but very often you look back onto code and refer to it very cynically as “Legacy” code. He’s argument was that “legacy” code is a result of progress in environment and personal growth (Sounds like a psychiatry session – I know – It did get better). He carried on by making suggestions as to how legacy code should be dealt with and then showed a few examples in Rails. Some thoughts suggestion:</p>
<ul>
<li>The worst mistake that a company can make is to decide to simply rewrite legacy code on impulse.</li>
<li>Legacy code should be put through iterations to improve it – They have a rule in their company that you should always leave code in a better state than what you found it in.</li>
<li>Be careful of judging code as legacy due to a change in personal taste.</li>
<li>Keep in mind that the code you write today will become legacy – face the facts.</li>
</ul>
<p>Rails developers make a big deal out of DRY (Do Not Repeat Yourself). It implies that functionality should not unnecessarily be repeated in your code. The rule of thumb is that if you have found yourself copy and pasting for the 3rd time then its time to DRY-up your code. His point was that very DRY code makes it sometimes difficult to extend the code and this can make the improvement of legacy code difficult. A bit of repetition in your code is thus not a bad thing.</p>
<p>A thought that came to my mind was – “How should the IT security consultant look at (or judge) legacy code. Firstly, code tested 2 years ago and stamped as secure might not be secure anymore (new techniques, new vulnerabilities). What, or rather, is there a recommendation on re-testing or frequency on re-testing? Secondly, what is the recommendation on finding holes in legacy code? As mentioned rewriting code is not always (very seldom) the viable solution. How should a client maintain a legacy code base from a security point of view?</p>
<p><strong>When to tell your kids about presentation caching – Matthew Deiters</strong></p>
<p>You have all heard about the 20/80 rule. You wear 20% of your clothes 80% of the time. 20% of the world’s population own 80% of the wealth. And so it turns out that 20% of an application resources are being requested 80% of the time and 80% of the http request time are being spent on the wire - thus the argument for caching and a few other tricks to speed things up.</p>
<p>From my notes and memory the following are the major points:</p>
<ul>
<li>Rails supports ETags. The application responds with an ETag in the HTTP header when a request has been made for specific resource. The browser caches the ETag and the contents. When requesting the same resource in future it sends the ETag back the server. This allows the server to check if anything on the resource has changed since the last request associated with the ETag. If it is still the same it responds with “not modified” (that take is quicker to process and send) and the browser just displays the old version.</li>
<li>Rails also supports static asset time stamping. This allows browser caching to be done based on a timestamp in the static asset request string.</li>
<li>Rails has setting “perform_caching true” that combines .js files into a single file and makes the download time quicker.</li>
<li>You can also configure your web server to gzip certain assets.</li>
<li>Because most web browsers only allows for 2 connections to run simultaneously to a single server there are advantages in distributing you static assets across multiple servers.</li>
</ul>
<p>All of the above have their little tricks and limitations that are worth investigating on implementation.</p>
<p><strong>Intellectual Scalability - Solving a Large Problem With Multiple Cooperating Rails Apps - Frederick Cheung (Texperts), Paul Butcher (Texperts)</strong></p>
<p>This was one of two presentations on serving multiple applications through a single front-end. In this case the developers designed a JavaScript heavy UI framework that presents the multiple allocations through a single front-end interface. Each application is presented in the front-end through what they call a widget. The power of the framework is in the code and a full (even partial) understanding requires a demonstration. I am making contact with the guy to see if they are willing to share the code. He did mention that they will release it publicly if there is interest.</p>
<p>Slides at <a title="http://assets.en.oreilly.com/1/event/13/Intellectual Scalability - Solving a Large Problem With Multiple Cooperating Rails Apps Presentation.ppt" href="http://assets.en.oreilly.com/1/event/13/Intellectual Scalability - Solving a Large Problem With Multiple Cooperating Rails Apps Presentation.ppt">http://assets.en.oreilly.com/1/event/13/Intellectual Scalability - Solving a Large Problem With Multiple Cooperating Rails Apps Presentation.ppt</a></p>
<p><strong>Offline Rails Applications with Google Gears and Adobe AIR - Till Vollmer (MindMeister/Codemart GmbH)</strong></p>
<p>(My notes are becoming increasingly less and I am not going to write a lot about this)<br />
This was more a Google Gears talk than a Rails talk. I have never bothered to actually have a look at Google Gears but this guy had a good talk on how they implemented it from an architectural point of view.</p>
<p>You basically design your web application to be able to operate when you are offline. You have a local SQLite database that you use when going offline and this is synchronised back to the server when you go back online. There is obviously at lot to manage:</p>
<ul>
<li>Detect on-line/off-line status</li>
<li>Clashes when local db and server are not compatible on synchronisation.</li>
</ul>
<p>My biggest thought during this talk was the amount of havoc that you can cause when the contents of the SQLite db is not validated before the automated synchronisation to the server db takes place. I think it is worth looking at.</p>
<p><strong>Security on Rails - Jonathan Weiss (Peritor GmbH)</strong></p>
<p>This is a German chap that is (amongst others) an IT security consultant. It had nothing too new about the web application security stuff – XSS, SQL injection and XSRF. He discussed in each case how this should be prevented in Rails. It was reassuring to note that our Rails development is up to his standards.</p>
<p>The interesting part of his talk was on how to finger print a Rails application. I will leave you with his slides to have a look at that: <a title="http://assets.en.oreilly.com/1/event/13/Security on Rails Presentation.pdf" href="http://assets.en.oreilly.com/1/event/13/Security on Rails Presentation.pdf">http://assets.en.oreilly.com/1/event/13/Security%20on%20Rails%20Presentation.pdf</a></p>
<p>Few other important things:</p>
<ul>
<li>Rails 2 and greater by default uses the cookie to store the session state (you can change this). This cookie is just Base64 encoded and should thus not be used to store sensitive data. A hash of the data and a secret key (you can configure this) is also stored in the cookie and this is used to check the authenticity of a cookie when send back to the server.</li>
<li>Some plugins to look at: saveERB, XSS shield and tidy_library.</li>
<li>Often times (and this is the case in some trusted plugins) the user session is not reset on logout – check for this.</li>
<li>Rails 2.1 and smaller - Despite the parameterise ability of the ActiveRecord class the limit and offset parameters in the find method where not typecased. This leaves the door open for SQL injections. This was fixed but the MySQL adapter still appears vulnerable.</li>
<li>Mass assignment (user = User.create(params) can allow for great havoc if the malicious user send extra parameters in the post request that relates for example to the user level. Use attr_protected and attr_accessible</li>
<li>DOS attacks can be launched against file upload functionalities by sending very big files. Use the web server to handle file uploads or use the web server direct the request to another application to deal with file uploads.</li>
</ul>
<p>I spoke to the guy afterwards to get an idea on what his opinion is on Rails’ maturity in terms of security. I mentioned a certain ‘trust’ in PHP due to the time it has had to mature. His reply was that Rails has been developed from a much better security perspective than Rails and is more mature to his standards.</p>
<p><strong>Functional Testing Lessons Learned - Jay Fields (DRW Trading)</strong></p>
<p>Jay mainly looked at the following three points:</p>
<ul>
<li>The place and role of writing tests</li>
<li>Comparing different test suites</li>
<li>Different types of tests</li>
</ul>
<p>He stressed the importance of testing and the purpose thereof. It is especially applicable in environments where code improvements, refactoring and growth is a constant occurrence. Testing plays a central role in making sure that the result of these actions does not break the code and that breaks in the code can be indentified as soon as possible. From a certain perspective testing is a way to document the functionality and purpose of code.</p>
<p>I picked up on the following statements two statements that I felt creates a great perspective:</p>
<ul>
<li>Testing code is just as important as application code.</li>
<li>Tests should be created that provides a positive return on investment</li>
</ul>
<p>An important point is that testing does not replace the need for manual testing – it does not replace a QA team or a testing team. Automated tests might test the intended functionality but the perspective from a person that is not involved in the development is needed.</p>
<p>The Rails framework encourages two testing approaches – Unit testing and Functional testing. Unit testing has to do with testing classes in isolation by simulating the functionality of dependencies to the outside of the class. Functional testing has to do with testing functionalities that is presented by the integration of different units. Have a look at his blog entry <a title="http://blog.jayfields.com/2007/09/rails-how-we-test.html" href="http://blog.jayfields.com/2007/09/rails-how-we-test.html">http://blog.jayfields.com/2007/09/rails-how-we-test.html</a> for more thoughts on this.</p>
<p>Other test types include integration tests, smoke tests, use case tests and automated browsers tests. I’ll leave it up to the reader to investigate these further.</p>
<p>Three testing suites were discussed:</p>
<ul>
<li>RSpec</li>
<li>test/unit</li>
<li>Selenium</li>
</ul>
<p>The factors to take into account when choosing a test suite are:</p>
<ul>
<li>Ease and simplicity of implementation</li>
<li>Flexibility to support the different types of tests</li>
<li>Ability to present the test code to non-technical project members – QA team, senior management etc.</li>
</ul>
<p>With these factors taken into account RSpec was considered the best option with test/unit in second and Selenium very unfavourable.</p>
<p>To bring the security aspect into this topic – I wonder if there is a case for security consultants to assist client developers in writing test cases for there applications that will also assist the developers in keeping a security perspective on there code.</p>
<p><strong><br />
</strong></p>
<p><strong>Small Things, Loosely Joined and Written Fast - Justin Gehtland (Relevance, Inc.)</strong></p>
<p>I think this was the best talk that I attended. Unfortunately for the reader of this article it was really one of those talks that you have had to been there. The slides was mainly a few photos to support his comical metaphors, my notes practically non-existent and an excellent demo that you’ll have to go though the code in your own time.</p>
<p>The main argument was – Big problems do not require big solutions bundled in one big fat application. Proper solutions consist of a number of small independent applications that can be developed, configured, tested and managed independently. These smaller solutions then be integrated together to tackle the big problem.</p>
<p>To use his terms – This approach will improve your productivity by improving:</p>
<ul>
<li>Testability</li>
<li>Compose-ability</li>
<li>Security</li>
<li>Scalability</li>
</ul>
<p>And, to quote him “Make small things, join them loosely, write them fast, scale them independently”</p>
<p>He had a wonderful demonstration on three Rails applications that are delivered through a single entry point using a central authentication point and a message queue for some of the communication between the independent parts.</p>
<p>Have a look at his blog entry - <a title="http://blog.thinkrelevance.com/2008/9/3/small-things-loosely-joined-written-fast" href="http://blog.thinkrelevance.com/2008/9/3/small-things-loosely-joined-written-fast">http://blog.thinkrelevance.com/2008/9/3/small-things-loosely-joined-written-fast</a></p>
<p><strong>From Rails Security to Application Security - Carsten Bormann (Universität Bremen, TZI), Steffen Bartsch (TZI, Universität Bremen)</strong></p>
<p>I am not going to attempt to cover this talk in too much depth. They touched on the topics of:</p>
<ul>
<li>Data confidentiality, integrity and authentication</li>
<li>Threat matrixes</li>
<li>Attack trees</li>
</ul>
<p>There is loads of information out there on this that makes covering the topics in this write-up irrelevant.</p>
<p>The one thing to take note of in this talk is an authorisation plugin that Steffen developed. It offers a very clean way to manage authorisation of access for different level users to all the levels of the MVC architecture. Despite offering great flexibility and full management of authorisation it has very clean way of presenting the authorisation rules to the developer, making the auditing of the rules a very easy process.</p>
<p>See the presentation slides on Steffen’s blog - <a title="http://steffenbartsch.com/blog/2008/09/from-rails-security-to-application-security/" href="http://steffenbartsch.com/blog/2008/09/from-rails-security-to-application-security/">http://steffenbartsch.com/blog/2008/09/from-rails-security-to-application-security/</a></p>
<p><strong>Writing resources_controller: Discovering REST Patterns in Rails - Ian White (Argument from Design)</strong></p>
<p>REST is getting great attention in the Rails community, in fact I will dare to say - I think the RAILS community are leaders in the RESTful approach. If I may quote Ralf Wirdemann and Thomas Baustert from RESTful Rails Development (<a title="http://media.quilime.com/files/pdf/restful_rails_en.pdf" href="http://media.quilime.com/files/pdf/restful_rails_en.pdf">http://media.quilime.com/files/pdf/restful_rails_en.pdf</a>) “REST describes an architecture paradigm for web applications that request and manipulate web resources using the standard HTTP methods GET, POST, PUT and DELETE.”. In other words - A resource (data object/model) is mapped to a URL and is managed by the standard HTTP methods.</p>
<p>Also and as mention earlier, Ruby programmers support DRY (Don’t Repeat Yourself) code.</p>
<p>Ian developed a plugin (seems like if you want to talk at Rails conference then you have to write a plugin) that provides a central Resource Controller that can manage the REST functionalities of all your other controllers. For a very thorough explanation of this see the blog - <a title="http://blog.ardes.com/resources_controller" href="http://blog.ardes.com/resources_controller">http://blog.ardes.com/resources_controller</a></p>
]]></content:encoded>
			<wfw:commentRss>http://usefulfor.com/ruby/2008/09/11/rails-conf-2008/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Ruby installer using NSIS (Part 1)</title>
		<link>http://usefulfor.com/ruby/2008/07/19/ruby-installer-in-nsis-using-hm-nis-edit-part-1/</link>
		<comments>http://usefulfor.com/ruby/2008/07/19/ruby-installer-in-nsis-using-hm-nis-edit-part-1/#comments</comments>
		<pubDate>Sat, 19 Jul 2008 19:50:49 +0000</pubDate>
		<dc:creator>siebert</dc:creator>
		
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://usefulfor.com/ruby/?p=63</guid>
		<description><![CDATA[On a recent project I was challenged with the task to create a Windows installer for the application that I have been contributing to (http://dradis.sourceforge.net/). After a bit of research it seemed like our answer was in using NSIS to assist us in this task.]]></description>
			<content:encoded><![CDATA[<h3>Intro</h3>
<p>On a recent project I was challenged with the task to create a Windows installer for <a title="Dradis" href="http://dradis.sourceforge.net/">Dradis</a>, an application that I have been contributing to. After a bit of research it seemed like our answer was in using <a title="http://nsis.sourceforge.net" href="http://nsis.sourceforge.net">NSIS</a> (Nullsoft Scriptable Install System) to assist us in this task.</p>
<p>NSIS in an open source platform for creating Windows installers. It has its own scripting language that you program all your installer logic in and then compiles to a Windows installer executable.</p>
<p>In this series of articles I will introduce you to:</p>
<ul>
<li>HM NIS IDE and it&#8217;s wizard (Part 1)</li>
<li>Customising the wizard code (Part 2)</li>
<li>Challenges with installing to user accounts without administrator rights (Part 3)</li>
</ul>
<p><span id="more-63"></span></p>
<h3>The goal</h3>
<p>The goal is to create an installer for Acme application. I will customise the installer code as we go along but the main components for installation are:</p>
<ul>
<li>Copying our acme_app.rb file to a location on the target machine</li>
<li>Check if Ruby is installed on the target machine. Install it if it is not the case</li>
<li>Our application uses SQLite. We need to check if the required files are installed on the target machine and install it if it is not the case.</li>
</ul>
<p>On the NSIS website you will find plenty of examples and tutorials to get you started. I am however going to jump in a little further ahead and tell you about <a title="HM NIS Edit" href="http://hmne.sourceforge.net">HM NIS Edit</a>. HM NIS Edit is an Editor/IDE to create your NSIS installers in. I came across it after a little web search and it proved itself to be a very handy tool to use on top of NSIS.</p>
<p>To create a nice installer with options, components, license etc. there is a lot of code that is generic and can fit into a framework followed by a bit of customisation. HM NSIS Edit assists you in this task by providing a wizard. It is from the wizard I&#8217;ll start my explanation.</p>
<h3>The HM NIS Edit wizard</h3>
<p>In the HM NSIS Edit application you have the typical wand and stars icon to start the wizard with. The first couple of screens is pretty straight forward and asks you a number of things about your app. The fun starts at the &#8220;Application Files&#8221; screen. It is here where you specify the different components (groups) for your application and the files associated.</p>
<h3>The application components</h3>
<p>For the purpose of my Acme application I create the following components: Ruby, SQLite and Acme app.</p>
<p><strong><em>1. Ruby</em></strong></p>
<p>For the Ruby component I do not see the point of wrapping the Ruby one click installer file in our Acme app installer. I decided I&#8217;ll make Ruby an install component but picking it for installation will download the Ruby one click installer and execute it. I create the Ruby group in the wizard and do not pick any files, we will add the meat of the download and install later.</p>
<p><strong><em>2. SQLite</em></strong></p>
<p>Now we get to the SQLite component. So we create the SQLite group in our wizard. This group consists of two parts: the dll and the Ruby gem.</p>
<p><em>sqlite3.dll</em></p>
<p>The dll is easy; it is one file that we need to copy to the system32 folder. So to the right hand side of the wizard window we click the add file icon, browse for the dll that we have ready on our machine and select the destination directory. The destination directory is the directory on the target machine where the file will be copied to. We need it in the system32 folder so we choose $SYSDIR from the drop down box.</p>
<p><em>SQLite gem</em></p>
<p>The most common way to install Ruby gem is with the command line command:</p>
<p><code>gem install GEMNAME --remote</code></p>
<p>In older GEM versions you could not however state the platform that you are installing the gem to from the command line, it is an option that is given to you just after running the &#8220;gem install GEMNAME &#8211;remote&#8221; command.</p>
<p>The above will not work very nice with our installer as we want the installer to deal with this and not require input from the user on gem installation. However you can use <code>--local</code> instead of <code>--remote</code> and just specify the local file from which the gem should be installed. In this case the installation does not require from you to supply the platform.</p>
<p>So I downloaded the sqlite3-ruby-1.2.1-mswin32.gem file from <a title="RubyForge" href="http://mirrors.cat.pdx.edu/rubyforge/rubyforge-gems/">RubyForge</a> and added it to the files to be installed as we did with the dll, however in this case just copy it to the $INSTDIR. We will add the meat to run the <code>gem install GEMNAME --remote</code> command later.</p>
<p><strong><em>3. Acme app</em></strong></p>
<p>Now we get to our acme_app.rb source file. As for the previous components we create a new component group called Acme app. After the component has been created be associate ou acme_app.rb source file with it as we did with the SQLite files. We set the $INSTDIR to be our target folder on the target machine.</p>
<p>Note - If your application code is more than one file you can select a directory tree to be associated with the component instead of just a single file at a time.</p>
<p>At this point you component list should look something similar to what you see in the figure below.</p>
<p><a href="http://usefulfor.com/ruby/files/2008/08/components.jpg"><img class="alignnone size-full wp-image-69" src="http://usefulfor.com/ruby/files/2008/08/components.jpg" alt="" width="500" height="383" /></a></p>
<p>Completing the rest of the wizard is quite straight forward. Remember that if you want to execute an executable (for instance if you want to call notepad to open a file at the end of installation) you have to give the full path to the executable (for example &#8220;$SYSDIR\notepad.exe some-text-file&#8221;).</p>
<p>Finishing the wizard will give you a code file that you can compile in HM NIS Edit and it will supply you with the install executable.</p>
<h3>That&#8217;s it for now</h3>
<p>- but there is more</p>
<p>I have left a few things out that the wizard could not do to customise our installer. I will have to do some tweaking to the code for this purpose. This will be covered in Part 2.</p>
<p class="MsoNormal"><span style="font-size: 10pt;font-family: Arial"> </span></p>
]]></content:encoded>
			<wfw:commentRss>http://usefulfor.com/ruby/2008/07/19/ruby-installer-in-nsis-using-hm-nis-edit-part-1/feed/</wfw:commentRss>
		</item>
		<item>
		<title>restful_authentication howto, step-by-step (part 2)</title>
		<link>http://usefulfor.com/ruby/2008/06/06/restful_authentication-howto-step-by-step-part-2/</link>
		<comments>http://usefulfor.com/ruby/2008/06/06/restful_authentication-howto-step-by-step-part-2/#comments</comments>
		<pubDate>Fri, 06 Jun 2008 01:36:46 +0000</pubDate>
		<dc:creator>etd</dc:creator>
		
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://weblog.nomejortu.com/ruby/restful_authentication-howto-step-by-step-part-2</guid>
		<description><![CDATA[Picking it up were we left it on restful_authentication howto, step-by-step (part 1) the second article of this series is a hands on example on how to use the restful_authentication plugin.
Things that will be covered include:

remove the need of a login
the use of an activation email, the application will require it&#8217;s users to activate their [...]]]></description>
			<content:encoded><![CDATA[<p>Picking it up were we left it on <a href="/ruby/2008/05/17/restful_authentication-step-by-step-part-1/">restful_authentication howto, step-by-step (part 1)</a> the second article of this series is a hands on example on how to use the <a href="http://agilewebdevelopment.com/plugins/restful_authentication">restful_authentication</a> plugin.</p>
<p>Things that will be covered include:</p>
<ul>
<li>remove the need of a <strong>login</strong></li>
<li>the use of an <em>activation email</em>, the application will require it&#8217;s users to activate their accounts upong sign up.</li>
<li>howto get rid of the <strong>remember me</strong> functionality (just in case you don&#8217;t need it).</li>
<li>howto strengthen a bit the default security of the framework.</li>
</ul>
<p><span id="more-55"></span><br />
If you started a blank application with the first series, you can seamlessly continue with the instructions of this post from were we left it on the first part of this <em>howto</em>. Otherwise, you can grab the code of <a href="/ruby/files/2008/06/restauthz.tar.bz2">restauthz</a> application, a small rails application that I have created and that can be used as a proof of concept out of the box. Let&#8217;s get this thing going.</p>
<p>Before we start, just a gentle reminder, be sure to include <code>AuthenticationSystem</code> in <code>ApplicationController</code>:-</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">include AuthenticatedSystem
</span><span class="hl-comment"># Filter the password and password_confirmation
# fields from the log files
</span><span class="hl-identifier">filter_parameter_logging</span><span class="hl-default"> :</span><span class="hl-identifier">password</span><span class="hl-default">, :</span><span class="hl-identifier">password_confirmation</span></pre></div></div>
<h3>no login, just email</h3>
<p>The first step is to remove the <code>login</code> field from the <code>User</code> migration, this will ensure that we do not use it in the code <img src='http://usefulfor.com/ruby/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>We also need to remove the revelant validatiors in the <code>User</code> model. In addition to this, some changes to the <code>authenticate</code> are required:-</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def self</span><span class="hl-default">.</span><span class="hl-identifier">authenticate</span><span class="hl-brackets">(</span><span class="hl-identifier">email</span><span class="hl-code">, </span><span class="hl-identifier">password</span><span class="hl-brackets">)
  </span><span class="hl-identifier">u</span><span class="hl-default"> = </span><span class="hl-identifier">find_in_state</span><span class="hl-default"> :</span><span class="hl-identifier">first</span><span class="hl-default">, :</span><span class="hl-identifier">active</span><span class="hl-default">, :</span><span class="hl-identifier">conditions</span><span class="hl-default"> =&amp;</span><span class="hl-identifier">gt</span><span class="hl-default">; {:</span><span class="hl-identifier">email</span><span class="hl-default"> =&amp;</span><span class="hl-identifier">gt</span><span class="hl-default">; </span><span class="hl-identifier">email</span><span class="hl-default">} </span><span class="hl-comment"># need to get the salt
  </span><span class="hl-identifier">u</span><span class="hl-default"> &amp;</span><span class="hl-identifier">amp</span><span class="hl-default">;&amp;</span><span class="hl-identifier">amp</span><span class="hl-default">; </span><span class="hl-identifier">u</span><span class="hl-default">.</span><span class="hl-identifier">authenticated</span><span class="hl-default">?</span><span class="hl-brackets">(</span><span class="hl-identifier">password</span><span class="hl-brackets">)</span><span class="hl-default"> ? </span><span class="hl-identifier">u</span><span class="hl-default"> : </span><span class="hl-reserved">nil
end</span></pre></div></div>
<p>We also need to update the call to this function in the <code>SessionsController</code> (line 9):-</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">self</span><span class="hl-default">.</span><span class="hl-identifier">current_user</span><span class="hl-default"> = </span><span class="hl-identifier">User</span><span class="hl-default">.</span><span class="hl-identifier">authenticate</span><span class="hl-brackets">(</span><span class="hl-identifier">params</span><span class="hl-brackets">[</span><span class="hl-code">:</span><span class="hl-identifier">email</span><span class="hl-brackets">]</span><span class="hl-code">, </span><span class="hl-identifier">params</span><span class="hl-brackets">[</span><span class="hl-code">:</span><span class="hl-identifier">password</span><span class="hl-brackets">])</span></pre></div></div>
<p>And that&#8217;s it. It wasn&#8217;t that difficult, was it?</p>
<h3>email activation</h3>
<p>The only thing that we are going to tweak is the templates provided by <strong>restful_authentication</strong>.</p>
<p>In <code>./app/model/user_mailer.rb</code> you can modify the email headers such as the <strong>subject</strong> and <strong>from</strong> address. The body of the emails is located under <code>./app/views/user_mailer/</code>.</p>
<p>The system sends to the users two emails, one after signup (this one contains the <em>activation link</em>) and one once the user has activated the account.</p>
<p>By default the templates contain the newly created user&#8217;s password, which is something that is controversial to say the least. I decided to get rid of the password, but this depends on your needs more than anything else.</p>
<h3>remember me</h3>
<p>Another feature that is application dependant is the use of a <em>remember me functionality</em>: a check box in the login form that would cause the application to store an authentication token in the user&#8217;s cookie so the next time the user visits the site does not have to authenticate again. I decided to nail down this example to the very basics, so no <em>remember me</em> functionality in this instance.</p>
<p>This can be accomplished by making some modifications to the <strong>AuthenticatedSystem#current_user</strong> function:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">current_user
  </span><span class="hl-comment">#@current_user ||= (login_from_session || login_from_basic_auth || login_from_cookie) unless @current_user == false
  # only session based login for the time being
  </span><span class="hl-var">@current_user</span><span class="hl-default"> ||= </span><span class="hl-identifier">login_from_session </span><span class="hl-reserved">unless </span><span class="hl-var">@current_user</span><span class="hl-default"> == </span><span class="hl-reserved">false
end</span></pre></div></div>
<p>In the previous code, the <code>@current_user</code> variable is only set through the session, no HTTP Basic (careful if you have ActiveResource clients) or <em>remember me</em> cookie.</p>
<h3>security tweaks</h3>
<p><strong>password policy</strong><br />
A strong password policy is enforced by means of rails&#8217; <a href="http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#M001331">validate_format_of</a>. In the <code>User</code> model:-</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">User</span><span class="hl-quotes">  /</span><span class="hl-string">^(?=.*</span><span class="hl-special">\d</span><span class="hl-string">)(?=.*([a-z]|[A-Z]))([</span><span class="hl-special">\x</span><span class="hl-string">20-</span><span class="hl-special">\x</span><span class="hl-string">7E]){8,40}$</span><span class="hl-quotes">/</span><span class="hl-default">,
    :</span><span class="hl-identifier">message</span><span class="hl-default"> =&amp;</span><span class="hl-identifier">gt</span><span class="hl-default">; </span><span class="hl-quotes">'</span><span class="hl-string">chosen is not complex enough!</span><span class="hl-quotes">'
  </span><span class="hl-identifier">validates_format_of</span><span class="hl-default"> :</span><span class="hl-identifier">email</span><span class="hl-default">, 
    :</span><span class="hl-identifier">with</span><span class="hl-default"> =&amp;</span><span class="hl-identifier">gt</span><span class="hl-default">;</span><span class="hl-quotes"> /</span><span class="hl-string">^([a-zA-Z0-9_'+*$%</span><span class="hl-special">\^</span><span class="hl-string">&amp;amp;!</span><span class="hl-special">\.\-</span><span class="hl-string">])+</span><span class="hl-special">\@</span><span class="hl-string">(([a-zA-Z0-9</span><span class="hl-special">\-</span><span class="hl-string">])+</span><span class="hl-special">\.</span><span class="hl-string">)+([a-zA-Z0-9:]{2,4})+$</span><span class="hl-quotes">/</span><span class="hl-default">, 
    :</span><span class="hl-identifier">message</span><span class="hl-default"> =&amp;</span><span class="hl-identifier">gt</span><span class="hl-default">; </span><span class="hl-quotes">'</span><span class="hl-string">field does not look like an email.</span><span class="hl-quotes">'
  </span><span class="hl-brackets">[</span><span class="hl-code">...</span><span class="hl-brackets">]
</span><span class="hl-reserved">end</span></pre></div></div>
<p>In the code above we match both the email and the password against regular expressions to verify the syntax.</p>
<p>The regular expression for the password was taken from <a href="http://ajaxonrails.wordpress.com/2006/10/19/using-regular-expression-in-ruby-on-rails-regex-for-password-validation/">Using Regular Expression in Ruby on Rails &#8212; Regexp for Password Validation</a>:-</p>
<blockquote><p>
Lets say we have to implement the following validations to validate a password:</p>
<ul>
<li>Password should contain atleast one integer.</li>
<li>Password should contain atleast one alphabet(either in downcase or upcase).</li>
<li>Password can have special characters from 20 to 7E ascii values.</li>
<li>Password should be minimum of 8 and maximum of 40 cahracters long.</li>
</ul>
</blockquote>
<p><strong>password with salt &amp; pepper</strong></p>
<blockquote><p>
Storing a password in plaintext may result in a system compromise (<a href="http://www.owasp.org/">OWASP</a>).
</p></blockquote>
<p>Conveniently enough, <strong>restful_authentication</strong> uses a <a href="http://en.wikipedia.org/wiki/Hash_function">hash function</a> to protect user passwords: the <a href="http://en.wikipedia.org/wiki/SHA-1">SHA-1</a>. It also uses a <a href="http://en.wikipedia.org/wiki/Salting_%28cryptography%29">salt</a>. Here are however two tricks to increase the security of the default setup:</p>
<p><strong>First</strong> we are going to hash the password with salt and pepper. The salt is specific to each user and will be stored in the database along with the user&#8217;s hashed password. If an attacker can compromise the database, they would have access to both the salt and the hash and brute force attacks could be mounted by using custom scripts or <a href="http://en.wikipedia.org/wiki/Rainbow_table">rainbow tables</a>. The trick here is to add a second component, the <strong>pepper</strong>. The pepper is another random string that will be used to add some extra entropy to the password hashing process. In our implementation the same pepper will be used for all the users and it will be stored in the code. If an attacker gains access to the database, no successful brute force attack can be mounted without knowing the pepper. If an attacker gains access to both the database and the code&#8230; <img src='http://usefulfor.com/ruby/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<p>You can easily generate your <strong>pepper</strong> using something like this in code in <code>irb</code>:-</p>
<div class="hl-surround">
<div class="hl-main">
<pre>
require 'digest/sha2'
s = ''
chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
1.upto(4) { |i| s &lt;&lt; chars[rand(chars.size-1)] }
s += Time.now.to_s
1.upto(4) { |i| s &lt;&lt; chars[rand(chars.size-1)] }
Digest::SHA256.hexdigest(s)
=&gt; &#8220;9fa4c6519da9d2121bc42be1d63813f591bba8ece5b753e6ceefed00f15e5342&#8243;
</pre>
</div>
</div>
<p>The random character generation was taken from <a href="http://snippets.dzone.com/posts/show/491">generate a random password</a>.</p>
<p>And <strong>second</strong>, we can upgrade the system to use the more secure SHA-256 both for the hashed password and the salt. We will keep SHA-1 for the sake of variety <img src='http://usefulfor.com/ruby/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>In order to accomplish this, some modifications are needed to the <code>./app/model/user.rb</code>. First we need to include the required files:-</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment"># sha1 for activation code. sha2 for the passwords
</span><span class="hl-reserved">require </span><span class="hl-quotes">'</span><span class="hl-string">digest/sha1</span><span class="hl-quotes">'
</span><span class="hl-reserved">require </span><span class="hl-quotes">'</span><span class="hl-string">digest/sha2</span><span class="hl-quotes">'</span></pre></div></div>
<p>Then the password encryption function:-</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment"># We are using both, salt and peper to hash the
# password. The new password hash uses
# SHA2.hexdigest
</span><span class="hl-reserved">def self</span><span class="hl-default">.</span><span class="hl-identifier">encrypt</span><span class="hl-brackets">(</span><span class="hl-identifier">password</span><span class="hl-code">, </span><span class="hl-identifier">salt</span><span class="hl-brackets">)
  </span><span class="hl-identifier">pepper</span><span class="hl-default"> = </span><span class="hl-quotes">'</span><span class="hl-string">9fa4c6519da9d2121bc42be1d63813f591bba8ece5b753e6ceefed00f15e5342</span><span class="hl-quotes">'
  </span><span class="hl-identifier">Digest</span><span class="hl-default">::</span><span class="hl-identifier">SHA256</span><span class="hl-default">.</span><span class="hl-identifier">hexdigest</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">--#{salt}--#{password}--#{pepper}--</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-reserved">end</span></pre></div></div>
<p>And the salt generation function:-</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment"># The salt is also created using SHA256
</span><span class="hl-reserved">def </span><span class="hl-identifier">encrypt_password
  </span><span class="hl-reserved">return if </span><span class="hl-identifier">password</span><span class="hl-default">.</span><span class="hl-identifier">blank</span><span class="hl-default">?
  </span><span class="hl-reserved">self</span><span class="hl-default">.</span><span class="hl-identifier">salt</span><span class="hl-default"> = </span><span class="hl-identifier">Digest</span><span class="hl-default">::</span><span class="hl-identifier">SHA256</span><span class="hl-default">.</span><span class="hl-identifier">hexdigest</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">--#{Time.now.to_s}--#{email}--</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">) </span><span class="hl-reserved">if </span><span class="hl-identifier">new_record</span><span class="hl-default">?
  </span><span class="hl-reserved">self</span><span class="hl-default">.</span><span class="hl-identifier">crypted_password</span><span class="hl-default"> = </span><span class="hl-identifier">encrypt</span><span class="hl-brackets">(</span><span class="hl-identifier">password</span><span class="hl-brackets">)
</span><span class="hl-reserved">end</span></pre></div></div>
<p>In order to store the new hash, we need to increase the length of the salt and crypted password fields in the database. This can be done in the migrations file:-</p>
<div class="hl-surround">
<div class="hl-main">
<pre>
t.column :crypted_password, :string, :limit =&gt; 64
t.column :salt, :string, :limit =&gt; 64
</pre>
</div>
</div>
<h3>summary</h3>
<p>So that was it, the <a href="/ruby/files/2008/06/restauthz.tar.bz2">restauthz</a> application should cover all the needs to get you started with restful_authentication. There is still room for improvement, think the <strong>I forgot my password</strong> functionality, or a facility for your users to change their passwords, but that is definitely another story <img src='http://usefulfor.com/ruby/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p>
]]></content:encoded>
			<wfw:commentRss>http://usefulfor.com/ruby/2008/06/06/restful_authentication-howto-step-by-step-part-2/feed/</wfw:commentRss>
		</item>
		<item>
		<title>restful_authentication howto, step-by-step (part 1)</title>
		<link>http://usefulfor.com/ruby/2008/05/17/restful_authentication-step-by-step-part-1/</link>
		<comments>http://usefulfor.com/ruby/2008/05/17/restful_authentication-step-by-step-part-1/#comments</comments>
		<pubDate>Fri, 16 May 2008 23:53:20 +0000</pubDate>
		<dc:creator>etd</dc:creator>
		
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://weblog.nomejortu.com/ruby/restful_authentication-step-by-step-part-1</guid>
		<description><![CDATA[There are more than a hundred thousand different ways of implementing authentication in ruby on rails. Authentication in the rails world is definetly not for the faint hearted. After some random reading through the rails wiki it seemed quite clear that there is one winner: acts_as_authenticated. However, after including this plugin in one of my [...]]]></description>
			<content:encoded><![CDATA[<p>There are <a href="http://wiki.rubyonrails.com/rails/pages/Authentication">more than a hundred thousand</a> different ways of implementing authentication in ruby on rails. Authentication in the rails world is definetly not for the faint hearted. After some random reading through the rails wiki it seemed quite clear that there is one winner: <a href="http://wiki.rubyonrails.org/rails/pages/acts_as_authenticated">acts_as_authenticated</a>. However, after including this plugin in one of my secret projects to take over the world, it seems that is lacking some functionality, what I need out of the authentication framework is:</p>
<ul>
<li>A no non-sense authentication: just email and password. No bells, no wistles.</li>
<li>The system should send an <em>activation email</em> after the user signs up.</li>
</ul>
<p>Let&#8217;s explore the alternatives <img src='http://usefulfor.com/ruby/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> <br />
<span id="more-53"></span></p>
<h3>The haystack&#8230;</h3>
<p>As stated elsewhere <strong>acts_as_authenticated</strong> is a neat solution that just <em>gets out of the way</em>. It is nice and easy to integrate. However, it is a bit too simple. <a href="http://rubyforge.org/projects/loginsugar/">loginsugar</a> seemed to be a suitable alternative with <a href="http://wiki.rubyonrails.org/rails/show/ActionMailer">ActionMailer</a> integration out of the box.</p>
<p>I decided to give it a try. It has a good documentation that walks you through the process of integrating it in your app, but it did not seem to be a goal too easy to accomplish <img src='http://usefulfor.com/ruby/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<p>What I finally decided was to take specific bits and pieces of the <strong>loginsugar</strong> and integrate them with plain old <strong>acts_as_authenticated</strong>.</p>
<p>First step of the process: I created a brand new project and installed the <strong>acts_as_authenticated</strong> plugin. It was surprising to find the following line in the README file:</p>
<blockquote><p>DEPRECATED: Use restful_authentication instead.  Or, ask me for commit rights if you wish to maintain this plugin.</p>
</blockquote>
<p>&#8230;  <img src='http://usefulfor.com/ruby/wp-includes/images/smilies/icon_rolleyes.gif' alt=':roll:' class='wp-smiley' /> So I was right back at the begining, everybody recommended <strong>acts_as_authenticated</strong> but <strong>acts_as_authenticated</strong> recommended <a href="http://agilewebdevelopment.com/plugins/restful_authentication">restuful_authentication</a>&#8230; I thought that if <strong>acts_as_authenticated</strong> is recommending something, it has to be good <img src='http://usefulfor.com/ruby/wp-includes/images/smilies/icon_mrgreen.gif' alt=':mrgreen:' class='wp-smiley' /> And I decided to give <strong>restuful_authentication</strong> a try.</p>
<h3>&#8230; and the needle</h3>
<p>Lets get out hands dirty, create a new project and install the plugin with:-</p>
<div class="hl-surround" ><div class="hl-main"><pre>&lt;br /&gt;
$ ./script/plugin  install http://svn.techno-weenie.net/projects/plugins/restful_authentication/&lt;br /&gt;</pre></div></div>
</p>
<p>It turns out that the plugin has the <em>activation email</em> functionality out of the box, the only requirement is the use of a few command line options:-</p>
<p>
<div class="hl-surround" ><div class="hl-main"><pre>&lt;br /&gt;
$ ./script/generate authenticated&lt;br /&gt;
Usage: ./script/generate authenticated ModelName [ControllerName]&lt;/p&gt;
&lt;p&gt;Options:&lt;br /&gt;
        --skip-migration             Don't generate a migration file for this model&lt;br /&gt;
        --include-activation         Generate signup 'activation code' confirmation via email&lt;br /&gt;
        --stateful                   Use acts_as_state_machine.  Assumes --include-activation&lt;br /&gt;
        --rspec                      Force rspec mode (checks for RAILS_ROOT/spec by default)&lt;br /&gt;</pre></div></div>
</p>
<p>We need to include the <code>--include-activation</code> for the email, which in turn requires <code>--stateful</code>. The idea is that you are going to associate a small <a href="http://en.wikipedia.org/wiki/State_Machine">state machine</a> to each user. From signed up, to pending; after the user actives the account, the status changes to active, etc.</p>
<p>It is quite neat. However it has the drawback that requires another plugin: <a href="http://agilewebdevelopment.com/plugins/acts_as_state_machine">acts_as_state_machine</a>, but more on that later.</p>
<p>In order to generate your user model and your session controller, you need to issue the following:-</p>
<p>
<div class="hl-surround" ><div class="hl-main"><pre>&lt;br /&gt;
$ ./script/generate authenticated user sessions \&lt;br /&gt;
                --include-activation \&lt;br /&gt;
                --stateful&lt;br /&gt;</pre></div></div>
</p>
<p>This generates the required files. It also creates the routes to the user and session resources in <code>./conf/routes.rb</code>:-</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-default">&lt;</span><span class="hl-identifier">br</span><span class="hl-quotes"> /</span><span class="hl-string">&gt;
#[...]&lt;br </span><span class="hl-quotes">/</span><span class="hl-default">&gt;
</span><span class="hl-identifier">map</span><span class="hl-default">.</span><span class="hl-identifier">resources</span><span class="hl-default"> :</span><span class="hl-identifier">users</span><span class="hl-default">&lt;</span><span class="hl-identifier">br</span><span class="hl-quotes"> /</span><span class="hl-string">&gt;
map.resource :session&lt;br </span><span class="hl-quotes">/</span><span class="hl-default">&gt;
</span><span class="hl-comment">#[...]&lt;br /&gt;</span></pre></div></div>
</p>
<p>However, as the README file suggests we need to modify the <code>:users</code> resource as follows:-</p>
<div class="hl-surround" ><div class="hl-main"><pre>&lt;br /&gt;
map.resources :users, :member =&gt; { :suspend =&gt; :put, :unsuspend =&gt; :put, :purge =&gt; :delete }&lt;br /&gt;</pre></div></div>
</p>
<p>An extra line in <code>./config/environment.rb</code> is also required (make sure you include it inside the <code>Rails::Initializer.run</code> block):-</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-default">&lt;</span><span class="hl-identifier">br</span><span class="hl-quotes"> /</span><span class="hl-string">&gt;
config.active_record.observers = :user_observer&lt;br </span><span class="hl-quotes">/</span><span class="hl-default">&gt;</span></pre></div></div>
</p>
<p>The next step is to install the <strong>acts_as_state_machine</strong> plugin and to run <code>rake db:migrate</code> to initialize the database:-</p>
<p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-default">&lt;</span><span class="hl-identifier">br</span><span class="hl-quotes"> /</span><span class="hl-string">&gt;
$ .</span><span class="hl-quotes">/</span><span class="hl-identifier">script</span><span class="hl-quotes">/</span><span class="hl-string">plugin install http:</span><span class="hl-quotes">//</span><span class="hl-string">elitists.textdriven.com</span><span class="hl-quotes">/</span><span class="hl-identifier">svn</span><span class="hl-quotes">/</span><span class="hl-string">plugins</span><span class="hl-quotes">/</span><span class="hl-identifier">acts_as_state_machine</span><span class="hl-quotes">/</span><span class="hl-string">trunk&lt;br </span><span class="hl-quotes">/</span><span class="hl-default">&gt;
</span><span class="hl-brackets">[</span><span class="hl-code">...</span><span class="hl-brackets">]</span><span class="hl-default">&lt;</span><span class="hl-identifier">br</span><span class="hl-quotes"> /</span><span class="hl-string">&gt;
$ rake db:migrate&lt;br </span><span class="hl-quotes">/</span><span class="hl-default">&gt;</span></pre></div></div>
</p>
<p>Now you are set. Feel free to run <code>rake</code> that all the tests will pass without warnings. Only one tip from the <a href="http://railscasts.com/episodes/67">restful_authentication railscast</a>: to get short urls for <code>signup</code>, <code>login</code> and <code>logout</code> add the following to your <code>./config/routes.rb</code>:</p>
<div class="hl-surround" ><div class="hl-main"><pre>&lt;br /&gt;
map.signup '/signup', :controller =&gt; 'users', :action =&gt; 'new'&lt;br /&gt;
map.connect '/activate/:activation_code', :controller =&gt; 'users', :action =&gt; 'activate'&lt;br /&gt;
map.login '/login', :controller =&gt; 'sessions', :action =&gt; 'new'&lt;br /&gt;
map.logout '/logout', :controller =&gt; 'sessions', :action =&gt; 'destroy'&lt;br /&gt;</pre></div></div>
</p>
<h3>Fine tune</h3>
<p>So here we are all set with the authentication framework in place. From here on it is about customization and fine tunning. Note that the <em>activation email</em> feature requires an either an email server running on the same box or some ActionMailer configuration in order for it to work.</p>
<p>In the second part of this series we will go back to our basic need: get rid of the <strong>login</strong> field (we only need an email). <del>This and other tweaks will be demonstrated in a tiny app that fully implements the concepts explained here.</del> Part 2 is here! <a href="/ruby/2008/06/06/restful_authentication-howto-step-by-step-part-2/">restful_authentication howto, step-by-step (part 2)</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://usefulfor.com/ruby/2008/05/17/restful_authentication-step-by-step-part-1/feed/</wfw:commentRss>
		</item>
		<item>
		<title>ruby application configuration settings</title>
		<link>http://usefulfor.com/ruby/2008/04/17/ruby-application-configuration-settings/</link>
		<comments>http://usefulfor.com/ruby/2008/04/17/ruby-application-configuration-settings/#comments</comments>
		<pubDate>Thu, 17 Apr 2008 09:53:46 +0000</pubDate>
		<dc:creator>etd</dc:creator>
		
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://weblog.nomejortu.com/?p=48</guid>
		<description><![CDATA[In this article I want to discuss a way of storing and retrieving the configuration settings of a ruby application. The first thing you need to decide is whether you want to store your settings in a database, a XML file, a YAML,&#8230;
Since this is not an easy choice we can mitigate the impact of [...]]]></description>
			<content:encoded><![CDATA[<p>In this article I want to discuss a way of storing and retrieving the configuration settings of a ruby application. The first thing you need to decide is whether you want to store your settings in a database, a XML file, a YAML,&#8230;</p>
<p>Since this is not an easy choice we can mitigate the impact of making the decision upfront by doing some interface based design.</p>
<p><span id="more-50"></span></p>
<p>I am going to use <a href="http://dradis.nomejortu.com/">dradis</a> as an example, but the code and philosophy are project independent.</p>
<p>First we put an interface together with all the methods that our configuration handling implementation will require. The <code>ParserInterface</code> should be implemented by all the different configuration parsers (xml, yaml, etc.). The idea is that the application and it&#8217;s modules will only access methods defined in this interface:-</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">module </span><span class="hl-identifier">ParserInterface
  </span><span class="hl-comment"># Given an option name (as a symbol) this function
  # retrieves the value stored in the configuration
  # file for it.
  </span><span class="hl-reserved">def </span><span class="hl-identifier">get_option</span><span class="hl-brackets">(</span><span class="hl-identifier">key</span><span class="hl-brackets">)
    </span><span class="hl-identifier">raise </span><span class="hl-quotes">'</span><span class="hl-string">unimplemented!</span><span class="hl-quotes">'
  </span><span class="hl-reserved">end

  </span><span class="hl-comment"># Store the given +value+ under the +key+ in the config
  # provider.
  </span><span class="hl-reserved">def </span><span class="hl-identifier">put_option</span><span class="hl-brackets">(</span><span class="hl-identifier">key</span><span class="hl-code">, </span><span class="hl-identifier">value</span><span class="hl-brackets">)
    </span><span class="hl-identifier">raise </span><span class="hl-quotes">'</span><span class="hl-string">unimplemented!</span><span class="hl-quotes">'
  </span><span class="hl-reserved">end

  </span><span class="hl-comment"># Store the configuration settings in the backend
  # provider.
  </span><span class="hl-reserved">def </span><span class="hl-identifier">save
    raise </span><span class="hl-quotes">'</span><span class="hl-string">unimplemented!</span><span class="hl-quotes">'
  </span><span class="hl-reserved">end
end</span></pre></div></div>
<p>We have defined methods for storing, retrieving and saving the configuration. It is true that the <code>save</code> may not be necessary if the implementation stores information in, for example, a database, however the advantage of having this method is that we are allowing our implementation to have a cached copy of the configuration settings in memory and only write them to the backend once the <code>save</code> method is called.</p>
<p>Ruby does not have native support for interfaces, this is why the <code>ParserInterface</code> is a ruby <strong>module</strong> and only defines methods that <a href="http://www.ruby-doc.org/docs/ProgrammingRuby/html/ref_m_kernel.html#Kernel.raise">raise</a> exceptions. We will include this module in our implementations, in doing so, the implementing classes will respond to the <code>get_option</code>, <code>put_option</code> and <code>save</code> methods straight away, but if the application calls any of them an exception will be thrown unless a valid implementation has been provided.</p>
<p>For <a href="http://dradis.nomejortu.com/">dradis</a> we are using an XML file as the backend configuration storage. The <a href="http://dradis.nomejortu.com/rdoc/classes/Core/Config/XMLParser.html">XMLParser</a> class. The full contents on the file can be accessed through the subversion repository in: <a href="http://dradis.svn.sourceforge.net/viewvc/dradis/client/branches/orko2.0-etd/core/config.rb?view=markup">/dradis/client/branches/orko2.0-etd/core/config.rb</a>. I have included below the interesting bits and pieces:-</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-comment"># to handle the XML part of it
</span><span class="hl-reserved">require </span><span class="hl-quotes">'</span><span class="hl-string">rexml/document</span><span class="hl-quotes">'

</span><span class="hl-reserved">class </span><span class="hl-identifier">XMLParser
  </span><span class="hl-comment"># include the interface
  </span><span class="hl-identifier">include ParserInterface

</span><span class="hl-comment">#[...]

# copy from the file into a hash in memory (initialize)
    </span><span class="hl-var">@src</span><span class="hl-default"> = </span><span class="hl-identifier">REXML</span><span class="hl-default">::</span><span class="hl-identifier">Document</span><span class="hl-default">.</span><span class="hl-identifier">new</span><span class="hl-brackets">(</span><span class="hl-identifier">File</span><span class="hl-code">.</span><span class="hl-identifier">new</span><span class="hl-brackets">(</span><span class="hl-var">@file</span><span class="hl-brackets">))
    </span><span class="hl-var">@options</span><span class="hl-default"> = {}
    </span><span class="hl-var">@src</span><span class="hl-default">.</span><span class="hl-identifier">elements</span><span class="hl-default">.</span><span class="hl-identifier">each</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">dradis/option</span><span class="hl-quotes">'</span><span class="hl-brackets">) </span><span class="hl-reserved">do</span><span class="hl-default"> |</span><span class="hl-identifier">element</span><span class="hl-default">|
      </span><span class="hl-var">@options</span><span class="hl-brackets">[</span><span class="hl-identifier">element</span><span class="hl-code">.</span><span class="hl-identifier">attributes</span><span class="hl-brackets">[</span><span class="hl-quotes">'</span><span class="hl-string">name</span><span class="hl-quotes">'</span><span class="hl-brackets">]</span><span class="hl-code">.</span><span class="hl-identifier">to_sym</span><span class="hl-brackets">]</span><span class="hl-default"> = </span><span class="hl-identifier">element</span><span class="hl-default">.</span><span class="hl-identifier">attributes</span><span class="hl-brackets">[</span><span class="hl-quotes">'</span><span class="hl-string">value</span><span class="hl-quotes">'</span><span class="hl-brackets">]
    </span><span class="hl-reserved">end

</span><span class="hl-comment"># get_option and put_option are straightforward

# [...]

  </span><span class="hl-reserved">def </span><span class="hl-identifier">save
    </span><span class="hl-comment"># if no change has been made to the configuration, do
    # not bother overwriting the file
    </span><span class="hl-reserved">return unless </span><span class="hl-var">@modified
    @options</span><span class="hl-default">.</span><span class="hl-identifier">each </span><span class="hl-reserved">do</span><span class="hl-default"> |</span><span class="hl-identifier">name</span><span class="hl-default">, </span><span class="hl-identifier">value</span><span class="hl-default">|
      </span><span class="hl-identifier">elements</span><span class="hl-default"> = </span><span class="hl-var">@src</span><span class="hl-default">.</span><span class="hl-identifier">get_elements</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">dradis/option[@name='#{name}']</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
      </span><span class="hl-reserved">if </span><span class="hl-brackets">(</span><span class="hl-identifier">elements</span><span class="hl-code">.</span><span class="hl-identifier">size</span><span class="hl-code">.</span><span class="hl-identifier">zero</span><span class="hl-code">?</span><span class="hl-brackets">)
        </span><span class="hl-comment"># a new element needs to be created
        </span><span class="hl-var">@src</span><span class="hl-default">.</span><span class="hl-identifier">root</span><span class="hl-default">.</span><span class="hl-identifier">add_element</span><span class="hl-brackets">( </span><span class="hl-quotes">'</span><span class="hl-string">option</span><span class="hl-quotes">'</span><span class="hl-code">, { </span><span class="hl-quotes">'</span><span class="hl-string">name</span><span class="hl-quotes">'</span><span class="hl-code"> =&amp;</span><span class="hl-identifier">gt</span><span class="hl-code">; </span><span class="hl-identifier">name</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">value</span><span class="hl-quotes">'</span><span class="hl-code"> =&amp;</span><span class="hl-identifier">gt</span><span class="hl-code">; </span><span class="hl-identifier">value</span><span class="hl-code">}</span><span class="hl-brackets">)
      </span><span class="hl-reserved">else
        </span><span class="hl-comment"># update the existing element
        </span><span class="hl-identifier">elements</span><span class="hl-default">.</span><span class="hl-identifier">first</span><span class="hl-default">.</span><span class="hl-identifier">attributes</span><span class="hl-brackets">[</span><span class="hl-quotes">'</span><span class="hl-string">value</span><span class="hl-quotes">'</span><span class="hl-brackets">]</span><span class="hl-default"> = </span><span class="hl-identifier">value
      </span><span class="hl-reserved">end
    end

    </span><span class="hl-comment"># use the Pretty formater to indent the file :)
    </span><span class="hl-identifier">fmt</span><span class="hl-default"> = </span><span class="hl-identifier">REXML</span><span class="hl-default">::</span><span class="hl-identifier">Formatters</span><span class="hl-default">::</span><span class="hl-identifier">Pretty</span><span class="hl-default">.</span><span class="hl-identifier">new</span><span class="hl-brackets">(</span><span class="hl-number">2</span><span class="hl-brackets">)
    </span><span class="hl-identifier">fmt</span><span class="hl-default">.</span><span class="hl-identifier">write</span><span class="hl-brackets">( </span><span class="hl-var">@src</span><span class="hl-code">, </span><span class="hl-identifier">File</span><span class="hl-code">.</span><span class="hl-identifier">new</span><span class="hl-brackets">(</span><span class="hl-var">@file</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">w</span><span class="hl-quotes">'</span><span class="hl-brackets">) )
  </span><span class="hl-reserved">end

</span><span class="hl-comment"># [...]
</span><span class="hl-reserved">end </span><span class="hl-comment"># class</span></pre></div></div>
<p>The only performance trick that I am using is the <code>@modified</code> variable that flags whether a change has been made to the configuration settings during the current session or not. If no change was made, there is no need to dump the <code>@options</code> hash back into the file.</p>
]]></content:encoded>
			<wfw:commentRss>http://usefulfor.com/ruby/2008/04/17/ruby-application-configuration-settings/feed/</wfw:commentRss>
		</item>
		<item>
		<title>ruby ToDo list</title>
		<link>http://usefulfor.com/ruby/2008/01/24/ruby-todo-list/</link>
		<comments>http://usefulfor.com/ruby/2008/01/24/ruby-todo-list/#comments</comments>
		<pubDate>Thu, 24 Jan 2008 14:42:27 +0000</pubDate>
		<dc:creator>etd</dc:creator>
		
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://weblog.nomejortu.com/?p=40</guid>
		<description><![CDATA[I have created a small Ruby on Rails application to keep track of my personal &#8220;ToDo&#8221; list of tasks. The idea is to split your different tasks into categories (i.e. important &#38; urgent, no important &#38; urgent, etc.) and have a web front end in which you can get a nice view of your pending [...]]]></description>
			<content:encoded><![CDATA[<p>I have created a small <a href="http://www.rubyonrails.org/">Ruby on Rails</a> application to keep track of my personal &#8220;ToDo&#8221; list of tasks. The idea is to split your different tasks into categories (i.e. important &amp; urgent, no important &amp; urgent, etc.) and have a web front end in which you can get a nice view of your pending tasks.<br />
<span id="more-42"></span><br />
<a href="/ruby/files/2008/06/todo.tar.bz2">The code</a> is under 1 MB and it <a href="http://wiki.rubyonrails.org/rails/pages/HowtoUseSQLite">works cool with sqlite3</a>. To run the application, go to the folder you uncompressed the file and issue the following command:-</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre>$ ./script/server</pre></div></div>
<p>Open a browser and access: <a href="http://localhost:3000/">http://localhost:3000/</a>.</p>
<p>The database provided contains some default categories and tasks. To remove them just go to the application directory and execute the following:</p>
<div class="hl-surround" ><div class="hl-main"><pre>$ ./script/console
&gt;&gt; Task.find(:all).each do |task| task.destroy end
&gt;&gt; Category.find(:all).each do |category| category.destroy end</pre></div></div>
<p>This will clear the database (note that you can also accomplish the same using the <code>rake db:migrate</code> command, however, that is another story <img src='http://usefulfor.com/ruby/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ). Then you need to add your own categories. Beware that the <acronym title="Cascading Style Sheets">CSS</acronym> file is prepared for up to 4 categories. Support for more could be easily added and is left as an exercise :D. to add you own categories:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre>Category.add</pre></div></div>
<p>Please note, that no special security measures have been implemented (SQL injection or XSS prevention). <strong>The tool is recommended to be used only in <em>safe</em> environments.</strong> <img src='http://usefulfor.com/ruby/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p>
]]></content:encoded>
			<wfw:commentRss>http://usefulfor.com/ruby/2008/01/24/ruby-todo-list/feed/</wfw:commentRss>
		</item>
		<item>
		<title>ruby workshop: the way of the Qt samurai</title>
		<link>http://usefulfor.com/ruby/2007/12/17/ruby-workshop-the-way-of-the-qt-samurai/</link>
		<comments>http://usefulfor.com/ruby/2007/12/17/ruby-workshop-the-way-of-the-qt-samurai/#comments</comments>
		<pubDate>Mon, 17 Dec 2007 16:23:56 +0000</pubDate>
		<dc:creator>etd</dc:creator>
		
		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[X Windows]]></category>

		<guid isPermaLink="false">http://weblog.nomejortu.com/?p=31</guid>
		<description><![CDATA[As a side result of my work with dradis during the last months, I&#8217;ve been working on some technical sessions that will be grouped in what could be called a &#8220;ruby workshop&#8221;. The first of this sessions is on ruby + Qt programming and is available now.

Slides can be found here.
Source and examples: here.

]]></description>
			<content:encoded><![CDATA[<p>As a side result of my work with <a href="http://dradis.nomejortu.com/">dradis</a> during the last months, I&#8217;ve been working on some technical sessions that will be grouped in what could be called a &#8220;ruby workshop&#8221;. The first of this sessions is on ruby + Qt programming and is available now.</p>
<ul>
<li>Slides can be found <a href="/ruby/files/2008/06/qtsamurai-slides.pdf">here</a>.</li>
<li>Source and examples: <a href="/ruby/files/2008/06/qtsamurai-code.tar.bz2">here</a>.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://usefulfor.com/ruby/2007/12/17/ruby-workshop-the-way-of-the-qt-samurai/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Net::DHCP</title>
		<link>http://usefulfor.com/ruby/2007/11/05/netdhcp/</link>
		<comments>http://usefulfor.com/ruby/2007/11/05/netdhcp/#comments</comments>
		<pubDate>Mon, 05 Nov 2007 17:59:05 +0000</pubDate>
		<dc:creator>etd</dc:creator>
		
		<category><![CDATA[Networking]]></category>

		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://weblog.nomejortu.com/?p=29</guid>
		<description><![CDATA[The aim of Net::DHCP (hosted at RubyForge)  is to provide a set of classes to low level handle the specifics of DHCP (rfc2131, rfc2132, etc.) in ruby.
With Net::DHCP you will be able to craft custom DHCP packages and have access to all the fields defined for the protocol.


The Dynamic Host Configuration Protocol (DHCP) provides [...]]]></description>
			<content:encoded><![CDATA[<p>The aim of <a href="http://rubyforge.org/projects/netdhcp/">Net::DHCP</a> (hosted at <a href="http://rubyforge.org/">RubyForge</a>)  is to provide a set of classes to low level handle the specifics of <acronym title="Dynamic Host Connection Protocol">DHCP</acronym> (<a href="http://www.ietf.org/rfc/rfc2131.txt">rfc2131</a>, <a href="http://www.ietf.org/rfc/rfc2132.txt">rfc2132</a>, etc.) in ruby.</p>
<p>With <a href="http://rubyforge.org/projects/netdhcp/">Net::DHCP</a> you will be able to craft custom <acronym title="Dynamic Host Connection Protocol">DHCP</acronym> packages and have access to all the fields defined for the protocol.<br />
<span id="more-34"></span></p>
<blockquote><p>
The Dynamic Host Configuration Protocol (DHCP) provides a framework for passing configuration information to hosts on a TCPIP network.
</p></blockquote>
<p><acronym title="User Datagram Protocol">UDP</acronym> is used as transport protocol, all packets sent by the client have a source port of 68 and a destination port of 67. Likewise, packets originated in the server will have source port 67 and destination port 68.</p>
<p>You can create messages, attach options and pack them as the payload of a <acronym title="User Datagram Protocol">UDP</acronym> packet. In the same way, you can use a capturing library such as Ruby/pcap to get packages from the network and parse their contents into well formed and comprehensible ruby objects.</p>
<p>This project&#8217;s SVN repository can be checked out through anonymous access with the following command(s):-<br />
<code><br />
svn checkout http://netdhcp.rubyforge.org/svn/<br />
or<br />
svn checkout svn://rubyforge.org/var/svn/netdhcp<br />
</code></p>
<p>I hope you find the library useful. Let me know if you are using it for something! <img src='http://usefulfor.com/ruby/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>References</strong></p>
<ul>
<li><a href="http://www.ietf.org/rfc/rfc2131.txt">rfc2131</a>: Dynamic Host Configuration Protocol</li>
<li><a href="http://www.ietf.org/rfc/rfc2132.txt">rfc2132</a>: DHCP Options and BOOTP Vendor Extensions</li>
<li><a href="http://www.ietf.org/rfc/rfc2563.txt">rfc2563</a>: DHCP Option to Disable Stateless Auto-Configuration in IPv4 Clients</li>
<li><a href="http://www.ietf.org/rfc/rfc4578.txt">rfc4578</a>: DHCP Options for the Intel Preboot eXecution Environment (PXE)</li>
<li><a href="http://www.ietf.org/rfc/rfc4702.txt">rfc4702</a>: The DHCP Client Fully Qualified Domain Name (FQDN) Option</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://usefulfor.com/ruby/2007/11/05/netdhcp/feed/</wfw:commentRss>
		</item>
		<item>
		<title>rComic: comic strip downloader</title>
		<link>http://usefulfor.com/ruby/2007/10/23/rcomic-comic-strip-downloader/</link>
		<comments>http://usefulfor.com/ruby/2007/10/23/rcomic-comic-strip-downloader/#comments</comments>
		<pubDate>Tue, 23 Oct 2007 12:26:56 +0000</pubDate>
		<dc:creator>etd</dc:creator>
		
		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Shell Script]]></category>

		<guid isPermaLink="false">http://weblog.nomejortu.com/?p=28</guid>
		<description><![CDATA[rComic is a small script to download and display Internet comic strips. To add new strips, you only need to modify the config file. And it is an interesting exercise to play with the Net::HTTP and YAML libraries.

rComic makes use of two external programs: wget and display for downloading and displaying the image. Both tools [...]]]></description>
			<content:encoded><![CDATA[<p>rComic is a small script to download and display Internet comic strips. To add new strips, you only need to modify the config file. And it is an interesting exercise to play with the <a href="http://www.ruby-doc.org/core/classes/Net/HTTP.html">Net::HTTP</a> and <a href="http://www.ruby-doc.org/core/classes/YAML.html">YAML</a> libraries.<br />
<span id="more-31"></span><br />
rComic makes use of two external programs: <code>wget</code> and <code>display</code> for downloading and displaying the image. Both tools are available as packages in all major distros (look for <code>imagemagick</code>). Get <a href="/ruby/files/2008/06/rcomic.tar.gz">the code</a> and let&#8217;s get it started.</p>
<p>To store the information of our comic strips we will be using <acronym title="YAML Ain'tMarkup Language">YAML</acronym>:</p>
<blockquote><p>The YAML library serializes and deserializes Ruby object trees to and from and external, readable, plain-text format.</p></blockquote>
<p>In the config file (<code>rcomic.yaml</code>) every comic strip definition will have the following appearance:</p>
<div class="hl-surround" ><div class="hl-main"><pre>xkcd:
  desc: A webcomic of romance, sarcasm, math, and language.
  host: www.xkcd.com
  path: /
  rexp: &lt;img&gt;</pre></div></div>
<p>You need a <strong>key word</strong> that will be used to refer to the strip and a set of configuration parameters, the host name, the path inside the server and a regular expression to identify the desired image.</p>
<p>In order to add a new strip, you only need to append a block like the one above to your configuration file.</p>
<p>Three steps are performed in the script: command line parsing, HTTP connection and download of the page, image download and display.  In order to know what strip are we working on, first we need to load the configuration file as show:-</p>
<div class="hl-surround" ><div class="hl-main"><pre>#load configuration
config = YAML.load_file('rcomic.yaml')</pre></div></div>
<p>Then some simple logic determines if the requested strip (the first argument provided) is configured in the <code>.yaml</code> file. If no reference to the <strong>key word</strong> is found  in the YAML file, a help message is displayed. Otherwise, we carry on with the next steps:</p>
<div class="hl-surround" ><div class="hl-main"><pre># prepare an HTTP connection
http = Net::HTTP.new($host)
# get the page
response = http.get($path)

# scan for the image
img = response.body.scan($rexp).first.first
file = File.basename(img)</pre></div></div>
<p>First we request the page and then we apply the regular expression to the body of the HTML returned. The <code>img</code> variable will contain the full URL to the image (i.e. <code>http://imgs.xkcd.com/comics/gyroscopes.png</code>) and the <code>file</code> will contain only the file name (i.e. <code>gyroscopes.png</code>).</p>
<p>With this information is dead easy to download and display the images:</p>
<div class="hl-surround" ><div class="hl-main"><pre># download (if not already downloaded)
unless File.exist?(&quot;/tmp/#{file}&quot;)
  `wget -O /tmp/#{file} #{img}`
end

# display
`display /tmp/#{file}`</pre></div></div>
<p>As a side note, we will only download the file if the file is not already present in our <code>/tmp/</code> folder.</p>
<p>Happy comics <img src='http://usefulfor.com/ruby/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p>
]]></content:encoded>
			<wfw:commentRss>http://usefulfor.com/ruby/2007/10/23/rcomic-comic-strip-downloader/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
