June 24, 2008

Posted by John

Tagged multisite, rspec, testing, and validation

Older: Alias Attribute

Newer: Raking /etc/hosts For Sweeter Subdomainage

Don't Forget To Reserve Subdomains For Yourself

In a certain application I’m working on, each account gets a unique subdomain. Something that is important, that most people don’t mention when showing examples of how to do account subdomainage, is how to reserve some for yourself and what are some good ones to reserve.

Here is a simplified version of the model I’m using:

class Account < ActiveRecord::Base
  ReservedSubdomains = %w[admin blog dev ftp mail pop pop3 imap smtp stage stats status www]
  validates_exclusion_of :subdomain, :in => ReservedSubdomains, :message => 'is not allowed'
end

Then in rSpec, I use the following to make sure that none of the reserved subdomains can be used. One note: the have_error_on in the code below is a matcher that is a part of the rspec-on-rails-matchers plugin.

describe Account do
  it "should not allow use of reserved subdomains" do
    Account::ReservedSubdomains.each do |subdomain|
      Account.new(:subdomain => subdomain).should have_error_on(:subdomain)
    end
  end
end

So nothing too difficult is going on up there. In fact, it is just out of the box Rails. The key, and the reason I post this, is to remind you to protect some of the important subdomains like mail, pop and smtp and some of the less important ones like blog and status for yourself.

14 Comments

  1. Luke Redpath Luke Redpath

    Jun 24, 2008

    Good suggestion, although I’d like to recommend a change to your spec. At the moment, it doesn’t really offer much protection. If somebody accidentally removed “www” from ReservedDomains, the spec would still pass because it is directly coupled to the implementation.

    Personally, I’d explicitly state the sub-domains in the test to stop this from happening (I think this is more important than the resulting duplication).

  2. @Luke – That’s a great point. I went back and forth a wee bit on the issue when I first put it in there and I’m thinking now I agree with you.

  3. I’m working on a project that also uses the subdomain-as-account-key pattern. I plan to use the blacklist approach outlined above as well as a minimum length:

    validates_length_of :subdomain, :minimum=>5

    It makes things a bit simpler to avoid having to manually list out all of the “standard” host names like www, ftp, pop, etc.

  4. @Josh – Yep, I didn’t show that but I have a minimum length as well. I think I set it at 6.

  5. Luke Redpath Luke Redpath

    Jun 27, 2008

    Just setting a validation on the length is a nice little shortcut, although it’s arguably not as obvious to other developers why you’ve done it (at least, without looking at the specs, but it could be easily missed).

  6. Ryan Heneise Ryan Heneise

    Jun 27, 2008

    I use a wee plugin called NameNanny (http://locusfoc.us/2007/2/13/name-nanny-plugin), which provides both bad_words and reserved_words lists. To use, just add this to your model:

    validates_wholesomeness_of :subdomain

    I like the NameNanny approach because the reserved words are stored in a file that can be modified independently of the code. My reserved words list is currently at 85 words and counting, with 776 prohibited bad words!

  7. Rick Sandhu Rick Sandhu

    Jun 29, 2008

    John,

    I want to pick your brain for a second, please have a look at my post over at Railsforum.com:

    http://railsforum.com/viewtopic.php?id=19738

    Since you’ve worked on an application using subdomain, I thought you would be good person to get some insight from…Thank you!

  8. I’ve just implemented something similar in an app I’m writing at the moment.

    However, I generated the specs as follows:

    
    describe Account do
      reserved = %w(list of subdomains)
      
      reserved.each do |subdomain|
        it "should reserve subdomain '#{subdomain}'" do    
          Account.new(:subdomain =&gt; subdomain).should have_error_on(:subdomain)
        end
      end
    end
    

    That way, you get told exactly which reserved subdomain isn’t protected.

    Instead of:
    > Account should not allow use of reserved subdomains FAILED

    You get:
    > Account should reserve subdomain ‘www’ FAILED

    Makes it much easier to track things down.

  9. @Ryan Heneise – this NameNanny is used by the the equivalent dot com domain ?

    I have a friend who had a bad experience with the above, meaning some info got “retrieved” from him.

  10. Rick Sandhu Rick Sandhu

    Jul 29, 2008

    Can you please share your thoughts on caching subdomain based applications using memcache? It’s hard to apply currently available reference to subdomain based applications.

  11. @Rick – Not sure I understand what subdomains have to do with memcache. Can you explain further?

  12. Rick Sandhu Rick Sandhu

    Aug 02, 2008

    Sorry for the confusion but let’s say I have the following setup:

    http://pastie.org/246376

    Community —> has_many —> Events
    Community —> has_many —> Categories
    Event —> belongs_to —> Community
    Event —> belongs_to —> Category
    Category —> belongs_to —> Community
    Category —> has_many —> Events

    How would I go about caching the ‘index’, ‘category’ and the ‘show’ actions in my Events controller using Rails 2.1 caching in conjunction with Memcache?

  13. Rick Sandhu Rick Sandhu

    Aug 05, 2008

    John,

    Thank you very much for your prompt reply. I really appreciate you taking the time to respond. That link really helped me on how to apply various caching patterns to large scale sites. Thanks, again!

Sorry, comments are closed for this article to ease the burden of pruning spam.

About

Authored by John Nunemaker (Noo-neh-maker), a programmer who has fallen deeply in love with Ruby. Learn More.

Projects

Flipper
Release your software more often with fewer problems.
Flip your features.