<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Stuff… And Things… &#187; Active Record</title>
	<atom:link href="http://stuff-things.net/category/active-record/feed/" rel="self" type="application/rss+xml" />
	<link>http://stuff-things.net</link>
	<description>Paradise is exactly like where you are right now only much, much better…</description>
	<lastBuildDate>Thu, 03 Jun 2010 00:24:23 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Introducing Strongbox</title>
		<link>http://stuff-things.net/2009/04/17/introducing-strongbox/</link>
		<comments>http://stuff-things.net/2009/04/17/introducing-strongbox/#comments</comments>
		<pubDate>Fri, 17 Apr 2009 16:49:59 +0000</pubDate>
		<dc:creator>Spike</dc:creator>
				<category><![CDATA[Active Record]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://stuff-things.net/?p=44</guid>
		<description><![CDATA[Over a year ago I wrote the wildly popular Encrypting Lots of Sensitive Data with Ruby (on Rails).  At the end I said:
Clearly, this screams for a plugin;  watch this space.
Well, it took a while and it turned out to be a gem, but Strongbox has arrived.
First a recap:
You have a web application [...]]]></description>
			<content:encoded><![CDATA[<p>Over a year ago I wrote the wildly popular <a href="http://stuff-things.net/2008/02/05/encrypting-lots-of-sensitive-data-with-ruby-on-rails">Encrypting Lots of Sensitive Data with Ruby (on Rails)</a>.  At the end I said:</p>
<blockquote><p>Clearly, this screams for a plugin;  watch this space.</p></blockquote>
<p>Well, it took a while and it turned out to be a gem, but <strong><a href="http://github.com/spikex/strongbox">Strongbox</a></strong> has arrived.</p>
<p>First a recap:</p>
<p>You have a web application and you need to encrypt the data your receive from your users.   The most common form of encryption is <a href="http://en.wikipedia.org/wiki/Symmetric_cryptography">symmetric-key encryption</a>, where one password is used for both encryption and decryption.  This works very well, but it means that everyone who enters data needs to know the password and everyone who knows the password can decrypt the data.</p>
<p>Enter <a href="http://en.wikipedia.org/wiki/Public-key_cryptography">Public-key cryptography</a> which used one password (key) to encrypt and a different key to decrypt.   This solves the problem; make the encryption password, the public key, available to your application, and keep  the decryption password, the private key, well, private.  Users don&#8217;t need to know or care how, they fill out a form and the data gets encrypted.  One small problem, size.  The most you can practically encrypt using this method is 245 bytes.  Good enough for the launch codes, but not so for driving directions to the buried treasure.</p>
<p>No problem, if we have larger data, we simply combine the two.  We generate a random password and use it to symmetrically encrypt to data.  We then use the public key to encrypt the random password.  To get the data back, the private key is used to decrypt the random password which is in turn used to decrypt the original data.</p>
<p>Got it?  Good. <a href="http://github.com/spikex/strongbox">Strongbox</a> takes the above three paragraphs and reduces them to this:</p>
<pre>class User &lt; ActiveRecord::Base
  encrypt_with_public_key :secret,
                          :key_pair =&gt; 'path/to/keypair.pem'
end

&gt;&gt; @user = User.new
&gt;&gt; @user.secret = 'Ssssh'
&gt;&gt; @user.secret  # =&gt; "*encrypted*"
&gt;&gt; user.secret.decrypt ‘letmein’ # =&gt; "Ssssh"</pre>
<p>OK, it&#8217;s sightly more complex.   The column &#8220;secret&#8221; needs to exist in the database and be type &#8220;binary&#8221; (more on this in a bit).  In additional, because we are using symmetric encryption (the default), we need two binary columns &#8220;secret_key&#8221; and &#8220;secret_iv&#8221; to store the generated symmetric key and <a href="http://en.wikipedia.org/wiki/Initialization_vector">Initialization vector (IV)</a> (which you can think of as a second key (but it&#8217;s <a href="http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation">not</a>) once they are encrypted with the public key.</p>
<p>If you are certain that the data you are encrypting won&#8217;t be larger than 245 bytes, you can use the following:</p>
<pre>class User &lt; ActiveRecord::Base
  encrypt_with_public_key :secret,
                          :key_pair =&gt; 'path/to/keypair.pem',
                          :symmetric =&gt; :never
  validates_length_of :secret, :maximum=&gt; 245
end</pre>
<p>This skips the symmetric encryption, is faster, and you only need the binary &#8220;secret&#8221; column.</p>
<p>You&#8217;ll also need to generate a key pair.  Be sure to choose a strong pass phrase, as this is the one that will decrypt everything (as always, I suggest using <a href="http://world.std.com/~reinhold/diceware.html">Diceware</a>).</p>
<pre><code>
% openssl genrsa -des3 -out private.pem 2048
Generating RSA private key, 2048 bit long modulus
......+++
.+++
e is 65537 (0x10001)
Enter pass phrase for key_pair.pem:
Verifying - Enter pass phrase for key_pair.pem:
</code></pre>
<p>If you aren&#8217;t going to be decrypting data on a regular basis you might want to deploy just the public key.  Extract it:</p>
<pre><code>
mv key_pair.pem private.pem
openssl rsa -in private.pem -out public.pem -outform PEM -pubout
Enter pass phrase for private.pem:
writing RSA key
</code></pre>
<p>And change your model:</p>
<pre>class User &lt; ActiveRecord::Base
  encrypt_with_public_key :secret,
                          :public_key =&gt; 'path/to/public.pem'
                          :private_key =&gt; 'path/to/private.pem'
end</pre>
<p>You could then have rake/Capistrano task to deploy and remove the private key as needed.  Or you could limit it&#8217;s use to a separate, non-public, server.</p>
<p>As noted  above you want your database column(s) to be binary.  If your database does not have a binary type you can add the <em>:base64</em> option:</p>
<pre>class User &lt; ActiveRecord::Base
  encrypt_with_public_key :secret,
                          :key_pair =&gt; 'path/to/keypair.pem',
                          :base64 =&gt; :true
end</pre>
<p>This will convert the binary data to text using Base64.  You must, <strong>must</strong> make your column type &#8220;text&#8221;.   Base64 increases the length of the data it encodes by approximately 137%.  Type &#8220;string&#8221; is typically 256 bytes, 245 * 1.37 = 335.65 bytes.   <em>If you use a &#8220;string&#8221; column and encrypt anything greater than 186 bytes <strong>your data will be lost</strong></em>.</p>
<p>Finally, there are two addition options for tweaking the encryption settings that you are unlikely to need:</p>
<p>&#8220;:symmetric_cipher&#8221; lets you change the algorithm that&#8217;s used for symmetric encryption.  The default is 256 bit <a href="http://en.wikipedia.org/wiki/Advanced_Encryption_Standard">Advanced Encryption Standard</a> (AES) using  <a href="http://en.wikipedia.org/wiki/Cipher_block_chaining">Cipher Block Chaining</a> (CBC) (&#8216;aes-256-cbc&#8217; in OpenSSL terms).   AES has been approved by the NSA for top secret information, so it&#8217;s probably good enough, but <a href="http://en.wikipedia.org/wiki/Blowfish_(cipher)">Blowfish</a> (&#8216;bf-cbc&#8217;) is know to work as well.  <a href="http://www.openssl.org/docs/apps/enc.html">Other ciphers in CBC mode</a> should also work, but have not been tested by me.  (Note that all ciphers may not be supported by your version of OpenSSL, &#8220;openssl list-cipher-commands&#8221; will provide a list.)</p>
<p>&#8220;:padding&#8221; allows you to change the method used to pad data encrypted with the public key.   Unless you are working with legacy data, you shouldn&#8217;t need to change this.  The default is &#8220;RSA_PKCS1_PADDING&#8221;, see the code if you need other options.</p>
<p><strong>Disclaimer</strong></p>
<p>I am not a security expert.  This software using an off the shelf encryption tool, namely <a href="http://www.openssl.org/">OpenSSL</a>, that has been well tested, but that is not a guarantee that this implementation doesn&#8217;t have weakness.  Be sure you understand what <em>Strongbox</em> does, and review it for your application.  A few things to keep in mind:</p>
<ul>
<li><em>Strongbox</em> encrypts the data as it is saved, but no sooner.  Be sure to use HTTPS for submitting the forms (and decrypting data!).</li>
<li>If an attacker gains entry to your system the encryption should protect your data.   However, they might be able to hack your code to intercept new data or, much worse, your private key password.  Protect your server.</li>
<li>When decrypting make sure your data isn&#8217;t cached.</li>
</ul>
<p>And test, test, test.  If there is a problem with how your data is encrypted, there is no getting it back.</p>
<p>One concern I have is garbage collection.  If you decrypt something into a variable which then goes out of scope, how long does it hang around in memory?  Can you force it out?  I haven&#8217;t found much information on this; if there are any Ruby GC experts out there, share your knowledge!</p>
<p>I am always open to suggestions and improvement, but, to quote the License:</p>
<blockquote><p>THE SOFTWARE IS PROVIDED &#8220;AS IS&#8221;, WITHOUT WARRANTY OF ANY<br />
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE<br />
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR<br />
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br />
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,<br />
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF<br />
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN<br />
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER<br />
DEALINGS IN THE SOFTWARE.</p></blockquote>
<p>So there!</p>
<p>Finally, I&#8217;d like to give a shout-out to <a href="http://www.thoughtbot.com/">thoughtbot</a>.    While this software has existed for many years, the final form of the gem was greatly inspired by <a href="http://www.thoughtbot.com/projects/paperclip">Paperclip</a>.   It&#8217;s a nice example of an approach to adding complex features to an ActiveRecord attribute and how to test them.   In additional, the gem sat unpublished for nearly a year because it needed test coverage and my testing was week.  Then I took thoughtbot&#8217;s <a href="http://www.thoughtbot.com/services/training/advanced-ruby-on-rails-boston">Advanced Ruby on Rails</a> class which really helped me get my head around testing and TDD, and got this moving again.  If you know Rails, but need to improve your processes, I highly recommend this class.</p>
]]></content:encoded>
			<wfw:commentRss>http://stuff-things.net/2009/04/17/introducing-strongbox/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Dealing with read-only fields and partial updates in Rails 1.x</title>
		<link>http://stuff-things.net/2008/09/03/dealing-with-read-only-fields-and-partial-updates-in-rails-1x/</link>
		<comments>http://stuff-things.net/2008/09/03/dealing-with-read-only-fields-and-partial-updates-in-rails-1x/#comments</comments>
		<pubDate>Wed, 03 Sep 2008 16:35:03 +0000</pubDate>
		<dc:creator>Spike</dc:creator>
				<category><![CDATA[Active Record]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://stuff-things.net/2008/09/03/dealing-with-read-only-fields-and-partial-updates-in-rails-1x/</guid>
		<description><![CDATA[So, you have a column in your database you can&#8217;t update after the record is created.   Not don&#8217;t want to update, but can&#8217;t.  Specifically, you might have a column that is protected by a trigger, which will cause an error if that column is included in a update.  How do you [...]]]></description>
			<content:encoded><![CDATA[<p>So, you have a column in your database you can&#8217;t update after the record is created.   Not <em>don&#8217;t want</em> to update, but <em>can&#8217;t</em>.  Specifically, you might have a column that is protected by a trigger, which will cause an error if that column is included in a update.  How do you prevent ActiveRecord from trying to update that column?</p>
<p>Prior to Rails 2.0, ActiveRecord will always generate an SQL UPDATE statement that includes all of the attributes in the model, even if they hadn&#8217;t changed.</p>
<pre name="code" class="ruby">
product = Product.find(:first)
=&gt; #&lt;Product:0x23a7d00 @attributes={"name"=&gt;"Product", "description"=&gt;"Lorem ipsum",  "price"=&gt;"9.99", "sku" =&gt; "000001"}&gt;
# Inflation
product.price += 1.00.to_d # You're not using floats for prices, are you?
product.save

=&gt; UPDATE products SET `price` = '10.99', `available` = 1, `description` = 'Lorem ipsum',  `name` = 'Product', `sku` = '000001' WHERE `id` = 1
</pre>
<p>If &#8220;sku&#8221; happens to be read-only, the update will fail, and so will your app.</p>
<p>The <em>right</em> way to fix this is to upgrade to Rails 2.x.   Starting 2.0 you can use attr_readonly which (silently) removes the attribute from the UPDATE statement.</p>
<pre name="code" class="ruby">
attr_readonly :sku
product = Product.find(:first)
=&gt; #&lt;Product:0x23a7d00 @attributes={"name"=&gt;"Product", "description"=&gt;"Lorem ipsum",  "price"=&gt;"9.99", "sku" =&gt; "000001"}&gt;
product.price += 1.00.to_d
product.save

=&gt; UPDATE products SET `price` = '10.99', `available` = 1, `description` = 'Lorem ipsum',  `name` = 'Product' WHERE `id` = 1
</pre>
<p>And, starting with 2.1, ActiveRecord only updates attributes that have been changed.  As long as you don&#8217;t change the value of an attribute, it won&#8217;t be included in the UPDATE statement.</p>
<pre name="code" class="ruby">
product = Product.find(:first)
=&gt; #&lt;Product:0x23a7d00 @attributes={"name"=&gt;"Product", "description"=&gt;"Lorem ipsum",  "price"=&gt;"9.99", "sku" =&gt; "000001"}&gt;
product.price  += 1.00.to_d
product.save

=&gt; UPDATE `products` SET `price` = '10.99'  WHERE `id` = 1
</pre>
<p>(Obviously, it&#8217;s better to explicitly mark an attribute as read-only then to depend on this behavior.)</p>
<p>But, what if you are working with a pre 2.X version of Rail?   As I said above, ActiveRecord generates the UPDATE statement based on the attributes in the model.  The trick, or should I say ugly hack, is to load the record with only the fields you want to update using <em>:select</em>.  This way, when the UPDATE is generate it will only include those attributes that were loaded into the record.</p>
<pre name="code" class="ruby">
product = Product.find(:first, :select =&gt; 'id, name, price')
=&gt; #&lt;Product:0x23a7d00 @attributes={"name"=&gt;"Product", "price"=&gt;"9.99", "id"=&gt;"1"}&gt;
product.price  += 1.00.to_d
product.save

=&gt; UPDATE `products` SET `price` = '10.99',   `name` = 'Product' WHERE `id` = 1
</pre>
<p>When doing this, you need to include the &#8220;id&#8221; column (or whatever your primary key is) in the select.   Also note that while this will work with find_by_ methods, find_or_initialize_by_ methods do not take the <em>:select</em> option.</p>
<p>Yup, it&#8217;s ugly but, it does, in fact, work.</p>
]]></content:encoded>
			<wfw:commentRss>http://stuff-things.net/2008/09/03/dealing-with-read-only-fields-and-partial-updates-in-rails-1x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quick and Dirty cropping images with attachment_fu</title>
		<link>http://stuff-things.net/2008/02/21/quick-and-dirty-cropping-images-with-attachment_fu/</link>
		<comments>http://stuff-things.net/2008/02/21/quick-and-dirty-cropping-images-with-attachment_fu/#comments</comments>
		<pubDate>Fri, 22 Feb 2008 03:30:55 +0000</pubDate>
		<dc:creator>Spike</dc:creator>
				<category><![CDATA[Active Record]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://stuff-things.net/2008/02/21/quick-and-dirty-cropping-images-with-attachment_fu/</guid>
		<description><![CDATA[Rick Olson&#8217;s attachment_fu is a great plugin for attaching files documents to Rails models.  It&#8217;s a rewrite of his acts_as_attachment plugin.  While it can handle any kind of file data, most commonly, it is used for attaching images; as a result attachment_fu handles automatic resizing of images, and creation of thumbnails using RMagick, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://techno-weenie.net/">Rick Olson&#8217;s</a> <a href="http://clarkware.com/cgi/blosxom/2007/02/24">attachment_fu</a> is a great plugin for attaching files documents to Rails models.  It&#8217;s a rewrite of his <a href="http://technoweenie.stikipad.com/plugins/show/Acts+as+Attachment">acts_as_attachment</a> plugin.  While it can handle any kind of file data, most commonly, it is used for attaching images; as a result attachment_fu handles automatic resizing of images, and creation of thumbnails using <a href="http://rmagick.rubyforge.org/">RMagick</a>, <a href="http://rubyforge.org/projects/mini-magick/">minimagick</a>, or <a href="http://seattlerb.rubyforge.org/ImageScience.html">ImageScience</a>.</p>
<p>For example:</p>
<pre name="code" class="ruby">
class ProductImage  &lt; ActiveRecord::Base
  belongs_to :product
  has_attachment :content_type =&gt; :image,
                 :storage =&gt; :file_system,
                 :path_prefix =&gt; '/public/images/products/',
                 :resize_to =&gt; '300',
                 :thumbnails =&gt; {:thumb =&gt; '75x75' }

  validates_as_attachment
end
</pre>
<p>The above will take an image, resize it to 300 pixels wide (automatically adjusting the height to preserve the original images aspect ratio),  and to 75 by 75 pixels for a thumbnail, and save resulting images.  Combined with a Product model that <em>has_one :image</em>, or <em>has_many :images</em>, and the right form, you can easily manage your product images.</p>
<p>However, an image with both a fixed width, and fixed height, like our thumbnail,  can be a problem. If the original, and resized image do not have the same aspect ratio the resized image will be distorted.   In this case, if the original is not square, our thumbnail will be look squished in which ever dimension was longer originally.  This is not a problem for the main image because we let the height be calculated automatically.</p>
<p>Fortunately, there is a simple trick that allows us to override the method attachment_fu uses to resize image and manipulate it ourselves.  Add the following to the ProductImage model:</p>
<pre name="code" class="ruby">
  protected

  # Override image resizing method
  def resize_image(img, size)
    # resize_image take size in a number of formats, we just want
    # Strings in the form of "crop: WxH"
    if (size.is_a?(String) &amp;&amp; size =~ /^crop: (\\d*)x(\\d*)/i) ||
        (size.is_a?(Array) &amp;&amp; size.first.is_a?(String) &amp;&amp;
          size.first =~ /^crop: (\\d*)x(\\d*)/i)
      img.crop_resized!($1.to_i, $2.to_i)
      # We need to save the resized image in the same way the
      # orignal does.
      self.temp_path = write_to_temp_file(img.to_blob)
    else
      super # Otherwise let attachment_fu handle it
    end
  end
</pre>
<p>and change the thumbnail size to:</p>
<pre>
<code>
:thumbnails =&gt; {:thumb =&gt; 'crop: 75x75' }
</code>
</pre>
<p>Now, if the image size starts with &#8216;crop: &#8216;, the image will be resized and then cropped to fit.  Otherwise, it&#8217;s passed on to attachment_fu and handed normally.   I&#8217;m using the RMagic <a href="http://www.imagemagick.org/RMagick/doc/image1.html#crop_resized_bang">crop_resized!</a> method, which resize the image using the smaller dimension and then crops the large one to fit.    If you are using minimagick, or ImageScience you may need to fiddle a bit with the code.  Obviously, you can extend this approach to manipulate the image anyway you see fit.   For example you could automatically put a border on the images:</p>
<pre name="code" class="ruby">
  def resize_image(img, size)
    # Add a 2x2 red border and pass the image to attachment_fu
    img.border!(2,2,'red')
    super
  end
</pre>
<p>Or blur them:</p>
<pre name="code" class="ruby">
  def resize_image(img, size)
    img = img.blur_image
    super # Pass the blured image to attachment_fu
  end
</pre>
<p>Or any other weirdness your heart desires.  Have fun!</p>
]]></content:encoded>
			<wfw:commentRss>http://stuff-things.net/2008/02/21/quick-and-dirty-cropping-images-with-attachment_fu/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
