The Blog

Ruby on Rails WebDAV Tutorial

web

Ever wanted a Devise authenticated, per-user chroot’d, WebDAV implementation for your Ruby on Rails application? Well I created one for a client and wrote a tutorial about it on Github!  Check it out:

Rails 3 WebDAV Tutorial with Custom Resources, Authentication with Devise, and User Specific Routing

The great gem DAV4Rack and its creator Chris Roberts deserve a huge shout-out.

Note: The tutorial is part of a Wiki and is subject to change.

Update: I built a sample app for this and it is available on Github: github.com/bryanrite/dav4rack-example-devise-subdirectories

Ruby on Rails CookieStore Security Concerns: Lifetime Pass

4839612753_d03954b19d_b

The CookieStore session storage in Ruby on Rails is not new; in fact, it has been the default session store since Rails 2.0. Since then, there have been countless blog posts and forum threads discussing various security concerns vs a server-sided store (ActiveRecordStore, Memcache, SqlStore, etc.). They all seem to miss an important point: by default, a stolen cookie gives the thief a lifetime pass to a user account!

I will explain how this happens and some steps you can implement to mitigate it.

Continue Reading →

Internationalization Strategies in ASP.Net (and lessons for other languages)

globalization and localization

Internationalization can be a tough area to do properly, in a scalable and manageable way. Most languages have their own system for handling different languages and cultures: Ruby uses its i10n library and YML files, PHP uses GNU gettext and PO files, while ASP.Net uses XML files presented by the IDE in a convenient way called Resource files.

I will explain some useful tips we learned while implementing Internationalization in our Cashless Schools project.

Continue Reading →

Remote Incremental Backups via Rsync and SSH to a Drobo

hardrive_000

A client had a catastrophic fileserver failure resulting in the loss of a significant amount of important data.  As a result,  I was called in to setup an automated offsite backup.  Due to many factors, I decided to implement a DroboFS instead of a hosted cloud or regular *nix fileserver.

Using the Drobo, there were a couple of gotchas.  It doesn’t have sshd enabled, no bash shell, no rsync (or rsnapshot which would make this easier) and more.

I will describe how I setup an automated, passwordless, incremental differential, hard-linked backup using rsync across ssh.

Continue Reading →

Are you an Interface Designer & Graphic Artist?

Are you a graphic artist and interface designer?

We’re looking for a great interface and graphic artist interested in working with our collective and getting in on some really exciting opportunities and projects.

Is This a Job?

No, not really.  What we’re looking for is a person interested in working on projects with us, getting in at the ground floor and collaborating on ideas brought to the table by our collective and external clients.

A lot of us have day jobs, these are projects and tasks we work on in our spare time.  They are passion projects for some, and great money-making ideas for others.  All projects are run on an opt-in basis, meaning you only work on what you want to be a part of.

Continue Reading →

Creating friendly UTF-8 Slug URLS

slug

A slug is a SEO-friendly, human-readable version of a URL. Generally used on most blog software for permalinks via a blog’s title (exactly like my blog here), or basically any string you want to turn into a friendly URL. Sure you could just use PHP’s urlencode (or other language equivalent) but then you’re stuck with unfriendly characters translated into hex codes: %2F%20

The problem is greater when the content you want to Slug is UTF-8 encoded and contains non-ASCII characters. How do you slug a word like: Iñtërnâtiônàlizætiøn?

Continue Reading →

Getting Imagemagick (and more) to work with MAMP on OS X

I’ve been using MAMP on my macbook for doing my web development at home and can’t say enough good things about it. Unfortunately I had to start using some binaries not included with MAMP, ImageMagick for example.

Update: Commentors have been reporting this fix is not working on Snow Leopard or MAMP 1.8.4

Installing ImageMagick via MacPorts is simple enough:

sudo port install ImageMagick

but trying to run it via the MAMP stack gives you the apache error:

dyld: Symbol not found: __cg_jpeg_resync_to_restart
  Referenced from: /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ImageIO.framework/Versions/A/ImageIO
  Expected in: /Applications/MAMP/Library/lib/libjpeg.62.dylib

or something similar. Continue Reading →

Updating Subversion to 1.5 on Ubuntu Hardy Heron

I was perusing the Ubuntu Hardy Heron backports repository and noticed that subversion had been added to the backports. If you’re reading this, you probably already know that you’re stuck with subversion 1.4 officially and unless you wanted to compile from source, or install a 3rd party .deb, you were pretty much out of luck.

Now that its been added to the backports repository, its a very simple to upgrade.

Continue Reading →

Repairing a Faulty Disk in a Software RAID Array

I was doing some system maintenance today and came across the following horrific screen:

/dev/md0:
        Version : 00.90.03
  Creation Time : Sun Nov 16 14:13:20 2007
     Raid Level : raid5
     Array Size : 732587712 (698.65 GiB 750.17 GB)
  Used Dev Size : 244195904 (232.88 GiB 250.06 GB)
   Raid Devices : 4
  Total Devices : 4
Preferred Minor : 0
    Persistence : Superblock is persistent

    Update Time : Wed Dec 31 10:41:15 2008
          State : clean, degraded
 Active Devices : 3
Working Devices : 3
 Failed Devices : 1
  Spare Devices : 0

...

    Number   Major   Minor   RaidDevice State
       0       0        0        0      removed
       1       8       17        1      active sync   /dev/sdb1
       2       8       33        2      active sync   /dev/sdc1
       3       8       49        3      active sync   /dev/sdd1
       4       8        1        -      faulty spare

One of the drives in my fileserver had died! Time to back up and get that sucker running again.

Please note: The following is only a guide to help you replace a failed disc. I cannot guarantee this will work for you, but it is what I do and has worked every time without any data loss.

As you can see, it is a 4 disc software RAID 5 array with no hotswap spares. The following should work for most single disc failure situations in RAID 1, 5, or 6.

It appears that sda has bailed on me. First things first, backup the machine. If anything happens, you can rebuild from scratch.

You can see the faulty disc has already been removed from the array, but if yours hasn’t been removed yet, the commands:

mdadm --manage /dev/md0 -f /dev/sda1
mdadm --manage /dev/md0 -r /dev/sda1

will mark it as failed (so it can be removed) and remove the sda1 partition.

Shutdown the machine and switch out the harddrives, make sure you only replace the faulty drive, don’t mess up the order of the drives cause it’ll be a pain to get it back in.

Boot up the machine. Your RAID array will be in the same degraded state. We need to partition the new drive exactly the same way we partitioned the drives in the existing array. Luckily this is a one-liner with sfdisk:

sfdisk -d /dev/sdb | sfdisk /dev/sda

The above code will dump the partition table of sdb (or use any of the functioning drives) and pipe it to sfdisk to partition sda the same way. It should only take a second.

Then we can simply add the new drive to the array:

mdadm --manage /dev/md0 -a /dev/sda1

Bam! If you take a look at cat /proc/mdstat or mdadm --detail /dev/md0 you should see that the array is recovering (with a percentage done).

After the recovery is done, you’ll be back to new and clean!

Good luck!

Select DISTINCT from DataSet

I’ve had tons of people ask me how to Select DISTINCT rows from a DataSet. Why not use SQL? Well sometimes you just can’t, and sometimes its much more efficient to do it webserver side then database side.

For some reason Microsoft has an article on how to write your own helper class, which is fine and dandy, but you don’t need to bother. While this implementation isn’t exactly the same as a SQL call, its very simple and works extremely well when working with medium to small datasets.

Say we have a DataSet ds like so:

recordID groupID value
1 100 abc
2 100 def
3 220 ghi
4 333 jkl

So to select distinct groupIDs we simply:

DataTable distinctDT = ds.Tables[0].DefaultView.ToTable(true, new string [] { "groupID" });

This returns:

groupID
100
220
333

We can now use this distinct DataTable to make our queries on our original DataSet:

ds.Tables[0].Select("groupID = " + distinctDT.Rows[0]["groupID"].toString());

That looks a little more complicated then it actually is… oh well, its actually quite a nice solution when you can’t use SQL to do your DISTINCT selects for you because you can use the same DataSet over and over reducing time to your SQL Server or FileIO.

Update Panel, GridView, and Non-asynchronous Postbacks in ASP.Net 2.0

In my latest job, I’ve been doing a lot of work with Microsoft and ASP.Net. I’ve recently started using the AJAX library for ASP.Net 2.0 and, while it has gone surprising well for the most part, there was one problem in general I couldn’t find an answer for online so I thought I’d post my solution.

Working with a GridView in an Update Panel is pretty quick and simple for many reasons, but when you require a full postback instead of an asynchronous one you can run into some trouble. If the actual object to cause the full postback has a set ID, no problem simply add:

<asp:UpdatePanel ...>
   <ContentTemplate>...</ContentTemplate>
   <Triggers>
      <asp:PostBackTrigger ControlID="CONTROL_ID" />
   </Triggers>
</asp:UpdatePanel>

The PostBackTrigger defined there will issue a full page postback. The problem arises on run-time controls such as a TemplateField or ButtonField within the GridView. There is no (easy) way to assign them as PostBackTrigger as either you don’t know the ID (in a ButtonField example) or the ID changes based on any MasterPages or panels. The solution is simple though.

Basically all we have to do is add the control to the Trigger collection in the code behind on the DataBind event of the item. This will work with any type of control you want to put in your GridView. In this example, I’ll use a LinkButton in a TemplateField.

... UpdatePanel definition etc. ...
<asp:GridView ...>
   <Columns>
      <asp:TemplateField>
         <ItemTemplate>
            <asp:LinkButton CommandName="Select" ID="PostBackButton"
                  runat="Server" Text="Do PostBack"
                  OnDataBinding="PostBackBind_DataBinding">
            </asp:LinkButton>
         </ItemTemplate>
     </asp:TemplateField>
     ... Any other Columns ...
   </Columns>
</asp:GridView>

Then in the codebehind:

protected void PostBackBind_DataBinding(object sender, EventArgs e)
{
   LinkButton lb = (LinkButton) sender;
   ScriptManager sm = (ScriptManager)Page.Master.FindControl("SM_ID");
   sm.RegisterPostBackControl(lb);
}

The script manager has a handy RegisterPostBackControl method and the link buttons are dynamically set as full postback calls.

Note: If you aren’t using a Master Page, you can just get the scriptmanager via its local reference: this.SM_ID.RegisterPostBackControl(lb);

Hope this helps someone out!