RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Build Robust Security into a Rails-Based Wiki System : Page 3

Learn how to add robust security features to a simple wiki system built on the Rails platform.

Changes to the Model Classes
The original RailsWiki application had a single model class called Wiki. This article splits this class into two classes, WikiUser and WikiDocument. The split is a clean way to have one class represent the user and another represent the user's documents (i.e., web pages). Listing 1 and Listing 2 contain the complete code for WikiUser and WikiDocument, respectively. Let's review the most notable methods in each of these classes.

WikiUser essentially provides authentication-related services by leveraging the Ruby Crypt library. Based on the descriptions of the various block ciphers supported by this library, I chose to use Blowfish.

The first interesting thing to note about this class is that it actually enables the user to create his or her own password file instead of requiring an administrator to do so. The password file itself is encrypted using the Blowfish cipher as demonstrated in the following code excerpt for the create_account method:

def create_account(plain_password)
      blowfish = Crypt::Blowfish.new(PASSWORD_KEY)
      f = open_file "w"

The remaining methods in the WikiUser class essentially provide additional authentication services such as validating an existing password, determining if the user account already exists, and so on.

The WikiDocument class is a bit more involved. It provides file-management services such as opening, saving, and deleting wiki files, getting a list of wiki file names in the user's directory, etc. Let's review the methods you need to add and change from the original RailsWiki application.

For starters, the self.save_encrypted method accepts the fully qualified path name of the wiki file to be created, along with a key to encrypt the plain text. This method first calls the internal mkdir method to ensure that the directory specified in the path variable exists. Then it creates the files and encrypts the plain text using the encrypt_string method of the Crypt::Blowfish class. The following code excerpt from the WikiDocument class demonstrates all of this:

def self.save_encrypted(path, content, key = nil)
    raise "key is nil or empty" if (key.nil? || key.empty?)
    mkdir path
    file = File.open(path, 'wb')
        blowfish = Crypt::Blowfish.new(key)

The other notable method in the WikiDocument class is find_encrypted. The key difference between this method and the find method that originally was part of the Wiki class is the extra step of decrypting the encrypted text using the decrypt_string method in the Crypt::Blowfish class, as shown in the following code excerpt:

def self.find_encrypted(path, key)
    raise "key is nil or empty" if (key.nil? || key.empty?)

    content = self.find(path)
    return "" if content.nil?

    blowfish = Crypt::Blowfish.new(key)
    blowfish.decrypt_string content

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date